mirror of
https://github.com/Valeh2012/PersonalVotingMachine
synced 2025-12-08 18:15:11 +02:00
first commit
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
#
|
||||
# Generic and Simple GNU ARM Makefile
|
||||
#
|
||||
# Desinged for the gnu-arm-none-eabi tool chain
|
||||
#
|
||||
# Features
|
||||
# - create hex file
|
||||
# - create assembler listing (.dis)
|
||||
#
|
||||
# Limitations
|
||||
# - only C-files supported
|
||||
# - no automatic dependency checking (call 'make clean' if any .h files are changed)
|
||||
#
|
||||
# Targets:
|
||||
# make
|
||||
# create hex file, no upload
|
||||
# make upload
|
||||
# create and upload hex file
|
||||
# make clean
|
||||
# delete all generated files
|
||||
#
|
||||
# Note:
|
||||
# Display list make database: make -p -f/dev/null | less
|
||||
#
|
||||
#================================================
|
||||
# External tools
|
||||
|
||||
# The base directory of gcc-arm-none-eabi
|
||||
# Can be empty on Ubuntu and installed gcc-arm-none-eabi
|
||||
# If set, GCCBINPATH must contain a "/" at the end.
|
||||
GCCBINPATH:=/usr/bin/
|
||||
|
||||
#================================================
|
||||
# Project Information
|
||||
|
||||
# The name for the project
|
||||
TARGETNAME:=eval_board
|
||||
|
||||
# The source files of the project
|
||||
CSRC:=$(wildcard *.c)
|
||||
SSRC:=$(wildcard ../stm32l0xx/src/*.s)
|
||||
|
||||
# The CPU architecture (will be used for -mcpu)
|
||||
# for the LPC824, can we use "cortex-m0plus"?
|
||||
MCPU:=cortex-m0plus
|
||||
|
||||
# Include directory for the system include files
|
||||
SYSINC:=../stm32l0xx/inc
|
||||
SYSSRC:=$(wildcard ../stm32l0xx/src/*.c)
|
||||
|
||||
# Include directory for the u8g2 include files
|
||||
U8G2INC:=./u8x8/
|
||||
U8G2SRC:=$(wildcard ./u8x8/*.c)
|
||||
|
||||
# Directory for the linker script
|
||||
LDSCRIPTDIR:=.
|
||||
# Name of the linker script (must be the "keep" script, because the other script is not always working)
|
||||
LDSCRIPT:=stm32l031x6.ld
|
||||
|
||||
#================================================
|
||||
# Main part of the Makefile starts here. Usually no changes are needed.
|
||||
|
||||
# Internal Variable Names
|
||||
LIBNAME:=$(TARGETNAME).a
|
||||
ELFNAME:=$(TARGETNAME).elf
|
||||
HEXNAME:=$(TARGETNAME).hex
|
||||
DISNAME:=$(TARGETNAME).dis
|
||||
MAPNAME:=$(TARGETNAME).map
|
||||
OBJ:=$(CSRC:.c=.o) $(SSRC:.s=.o) $(SYSSRC:.c=.o) $(U8G2SRC:.c=.o)
|
||||
# $(SYSSRC:.c=.o) $(FFSRC:.c=.o)
|
||||
|
||||
# Replace standard build tools by arm tools
|
||||
AS:=$(GCCBINPATH)arm-none-eabi-as
|
||||
CC:=$(GCCBINPATH)arm-none-eabi-gcc
|
||||
AR:=$(GCCBINPATH)arm-none-eabi-ar
|
||||
OBJCOPY:=$(GCCBINPATH)arm-none-eabi-objcopy
|
||||
OBJDUMP:=$(GCCBINPATH)arm-none-eabi-objdump
|
||||
SIZE:=$(GCCBINPATH)arm-none-eabi-size
|
||||
|
||||
# Common flags
|
||||
COMMON_FLAGS = -mthumb -mcpu=$(MCPU)
|
||||
COMMON_FLAGS += -DSTM32L031xx
|
||||
COMMON_FLAGS += -Wall -I. -I$(SYSINC) -I$(U8G2INC)
|
||||
# define stack size (defaults to 0x0100)
|
||||
# COMMON_FLAGS += -D__STACK_SIZE=0x0100
|
||||
# COMMON_FLAGS += -Os -flto
|
||||
COMMON_FLAGS += -Os
|
||||
# COMMON_FLAGS += -fstack-protector
|
||||
# COMMON_FLAGS += -finstrument-functions
|
||||
# Do not use stand libs startup code. Uncomment this for gcclib procedures
|
||||
# memcpy still works, but might be required for __aeabi_uidiv
|
||||
# COMMON_FLAGS += -nostdlib
|
||||
# remove unused data and function
|
||||
#COMMON_FLAGS += -ffunction-sections -fdata-sections -fshort-wchar
|
||||
COMMON_FLAGS += -ffunction-sections -fdata-sections
|
||||
# the following seems to be required for newlib nano
|
||||
# COMMON_FLAGS += -fno-builtin
|
||||
# C flags
|
||||
CFLAGS:=$(COMMON_FLAGS) -std=gnu99
|
||||
# LD flags
|
||||
# remove unreferenced procedures and variables, but __isr_vector
|
||||
GC:=-Wl,--gc-sections -Wl,--undefined=__isr_vector
|
||||
MAP:=-Wl,-Map=$(MAPNAME)
|
||||
LFLAGS:=$(COMMON_FLAGS) $(GC) $(MAP)
|
||||
#LDLIBS:=--specs=nosys.specs -lc -lc -lnosys -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
|
||||
LDLIBS:=--specs=nosys.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
|
||||
#LDLIBS:=--specs=nano.specs -specs=nosys.specs -L$(LDSCRIPTDIR) -T $(LDSCRIPT)
|
||||
|
||||
# Additional Suffixes
|
||||
.SUFFIXES: .elf .hex .bin .dis
|
||||
|
||||
# Targets
|
||||
.PHONY: all
|
||||
all: $(DISNAME) $(HEXNAME)
|
||||
$(SIZE) $(ELFNAME)
|
||||
|
||||
.PHONY: upload
|
||||
upload: $(DISNAME) $(HEXNAME) $(ELFNAME)
|
||||
stm32flash -e 255 -g 0 -w $(HEXNAME) -v /dev/ttyUSB0
|
||||
$(SIZE) $(ELFNAME)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) $(OBJ) $(HEXNAME) $(ELFNAME) $(LIBNAME) $(DISNAME) $(MAPNAME) libssp.a libssp_nonshared.a
|
||||
|
||||
# implicit rules
|
||||
.elf.hex:
|
||||
$(OBJCOPY) -O ihex $< $@
|
||||
|
||||
|
||||
|
||||
# explicit rules
|
||||
|
||||
$(ELFNAME): $(LIBNAME)($(OBJ)) libssp.a libssp_nonshared.a
|
||||
$(LINK.o) $(LFLAGS) $(LIBNAME) $(LDLIBS) -o $@
|
||||
|
||||
$(DISNAME): $(ELFNAME)
|
||||
$(OBJDUMP) -D -S $< > $@
|
||||
|
||||
# create empty ssp libs for -fstack-protector-all -fstack-protector
|
||||
libssp.a:
|
||||
$(AR) rcs $@
|
||||
|
||||
libssp_nonshared.a:
|
||||
$(AR) rcs $@
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
delay.c
|
||||
|
||||
The delay function delay_micro_seconds() will use the global variable
|
||||
SystemCoreClock. A call to SystemCoreClockUpdate() is required before
|
||||
using delay_micro_seconds().
|
||||
|
||||
STM32L031 Project (U8g2 Library)
|
||||
|
||||
Copyright (c) 2017, 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 "stm32l031xx.h"
|
||||
|
||||
/* Generic ARM delay procedure, based on the system timer (SysTick) */
|
||||
|
||||
/*
|
||||
Delay by the provided number of system ticks.
|
||||
The delay must be smaller than the RELOAD value.
|
||||
This delay has an imprecision of about +/- 20 system ticks.
|
||||
*/
|
||||
static void _delay_system_ticks_sub(uint32_t sys_ticks)
|
||||
{
|
||||
uint32_t start_val, end_val, curr_val;
|
||||
uint32_t load;
|
||||
|
||||
start_val = SysTick->VAL;
|
||||
start_val &= 0x0ffffffUL;
|
||||
end_val = start_val;
|
||||
|
||||
if ( end_val < sys_ticks )
|
||||
{
|
||||
/* check, if the operation after this if clause would lead to a negative result */
|
||||
/* if this would be the case, then add the reload value first */
|
||||
load = SysTick->LOAD;
|
||||
load &= 0x0ffffffUL;
|
||||
end_val += load;
|
||||
}
|
||||
/* counter goes towards zero, so end_val is below start value */
|
||||
end_val -= sys_ticks;
|
||||
|
||||
|
||||
/* wait until interval is left */
|
||||
if ( start_val >= end_val )
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
curr_val = SysTick->VAL;
|
||||
curr_val &= 0x0ffffffUL;
|
||||
if ( curr_val <= end_val )
|
||||
break;
|
||||
if ( curr_val > start_val )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
curr_val = SysTick->VAL;
|
||||
curr_val &= 0x0ffffffUL;
|
||||
if ( curr_val <= end_val && curr_val > start_val )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Delay by the provided number of system ticks.
|
||||
Any values between 0 and 0x0ffffffff are allowed.
|
||||
*/
|
||||
void delay_system_ticks(uint32_t sys_ticks)
|
||||
{
|
||||
uint32_t load4;
|
||||
load4 = SysTick->LOAD;
|
||||
load4 &= 0x0ffffffUL;
|
||||
load4 >>= 2;
|
||||
|
||||
while ( sys_ticks > load4 )
|
||||
{
|
||||
sys_ticks -= load4;
|
||||
_delay_system_ticks_sub(load4);
|
||||
}
|
||||
_delay_system_ticks_sub(sys_ticks);
|
||||
}
|
||||
|
||||
/*
|
||||
Delay by the provided number of micro seconds.
|
||||
Limitation: "us" * System-Freq in MHz must not overflow in 32 bit.
|
||||
Values between 0 and 1.000.000 (1 second) are ok.
|
||||
|
||||
Important: Call SystemCoreClockUpdate() before calling this function.
|
||||
*/
|
||||
void delay_micro_seconds(uint32_t us)
|
||||
{
|
||||
uint32_t sys_ticks;
|
||||
|
||||
sys_ticks = SystemCoreClock;
|
||||
sys_ticks /=1000000UL;
|
||||
sys_ticks *= us;
|
||||
delay_system_ticks(sys_ticks);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
delay.h
|
||||
|
||||
LPC11U3x GPS Logger (https://github.com/olikraus/lpc11u3x-gps-logger)
|
||||
|
||||
Copyright (c) 2016, 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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _DELAY_H
|
||||
#define _DELAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
Delay by the provided number of system ticks.
|
||||
Any values between 0 and 0x0ffffffff are allowed.
|
||||
*/
|
||||
void delay_system_ticks(uint32_t sys_ticks);
|
||||
|
||||
/*
|
||||
Delay by the provided number of micro seconds.
|
||||
Limitation: "us" * System-Freq in MHz must now overflow in 32 bit.
|
||||
Values between 0 and 1.000.000 (1 second) are ok.
|
||||
|
||||
Important: Call SystemCoreClockUpdate() before calling this function.
|
||||
*/
|
||||
void delay_micro_seconds(uint32_t us);
|
||||
|
||||
#endif /* _DELAY_H */
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
|
||||
Example for the STM32L031 Eval Board with 128x64 OLED at PA13/PA14
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "stm32l031xx.h"
|
||||
#include "delay.h"
|
||||
#include "u8x8.h"
|
||||
|
||||
/*=======================================================================*/
|
||||
/* external functions */
|
||||
uint8_t u8x8_gpio_and_delay_stm32l0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
|
||||
/*=======================================================================*/
|
||||
/* global variables */
|
||||
|
||||
u8x8_t u8x8; // u8x8 object
|
||||
uint8_t u8x8_x, u8x8_y; // current position on the screen
|
||||
|
||||
volatile unsigned long SysTickCount = 0;
|
||||
|
||||
/*=======================================================================*/
|
||||
|
||||
void __attribute__ ((interrupt, used)) SysTick_Handler(void)
|
||||
{
|
||||
SysTickCount++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setHSIClock()
|
||||
{
|
||||
|
||||
/* test if the current clock source is something else than HSI */
|
||||
if ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
|
||||
{
|
||||
/* enable HSI */
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
/* wait until HSI becomes ready */
|
||||
while ( (RCC->CR & RCC_CR_HSIRDY) == 0 )
|
||||
;
|
||||
|
||||
/* enable the HSI "divide by 4" bit */
|
||||
RCC->CR |= (uint32_t)(RCC_CR_HSIDIVEN);
|
||||
/* wait until the "divide by 4" flag is enabled */
|
||||
while((RCC->CR & RCC_CR_HSIDIVF) == 0)
|
||||
;
|
||||
|
||||
|
||||
/* then use the HSI clock */
|
||||
RCC->CFGR = (RCC->CFGR & (uint32_t) (~RCC_CFGR_SW)) | RCC_CFGR_SW_HSI;
|
||||
|
||||
/* wait until HSI clock is used */
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
|
||||
;
|
||||
}
|
||||
|
||||
/* disable PLL */
|
||||
RCC->CR &= (uint32_t)(~RCC_CR_PLLON);
|
||||
/* wait until PLL is inactive */
|
||||
while((RCC->CR & RCC_CR_PLLRDY) != 0)
|
||||
;
|
||||
|
||||
/* set latency to 1 wait state */
|
||||
FLASH->ACR |= FLASH_ACR_LATENCY;
|
||||
|
||||
/* At this point the HSI runs with 4 MHz */
|
||||
/* Multiply by 16 device by 2 --> 32 MHz */
|
||||
RCC->CFGR = (RCC->CFGR & (~(RCC_CFGR_PLLMUL| RCC_CFGR_PLLDIV ))) | (RCC_CFGR_PLLMUL16 | RCC_CFGR_PLLDIV2);
|
||||
|
||||
/* enable PLL */
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
|
||||
/* wait until the PLL is ready */
|
||||
while ((RCC->CR & RCC_CR_PLLRDY) == 0)
|
||||
;
|
||||
|
||||
/* use the PLL has clock source */
|
||||
RCC->CFGR |= (uint32_t) (RCC_CFGR_SW_PLL);
|
||||
/* wait until the PLL source is active */
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
|
||||
;
|
||||
|
||||
SystemCoreClockUpdate(); /* Update SystemCoreClock global variable */
|
||||
}
|
||||
|
||||
/*
|
||||
Enable several power regions: PWR, GPIOA
|
||||
|
||||
This must be executed after each reset.
|
||||
*/
|
||||
void startUp(void)
|
||||
{
|
||||
RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
|
||||
RCC->APB1ENR |= RCC_APB1ENR_PWREN; /* enable power interface (PWR) */
|
||||
PWR->CR |= PWR_CR_DBP; /* activate write access to RCC->CSR and RTC */
|
||||
|
||||
SysTick->LOAD = (SystemCoreClock/1000)*50 - 1; /* 50ms task */
|
||||
SysTick->VAL = 0;
|
||||
SysTick->CTRL = 7; /* enable, generate interrupt (SysTick_Handler), do not divide by 2 */
|
||||
}
|
||||
|
||||
/*=======================================================================*/
|
||||
/* u8x8 display procedures */
|
||||
|
||||
void initDisplay(void)
|
||||
{
|
||||
u8x8_Setup(&u8x8, u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_i2c, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_stm32l0);
|
||||
u8x8_InitDisplay(&u8x8);
|
||||
u8x8_ClearDisplay(&u8x8);
|
||||
u8x8_SetPowerSave(&u8x8, 0);
|
||||
u8x8_SetFont(&u8x8, u8x8_font_amstrad_cpc_extended_r);
|
||||
u8x8_x = 0;
|
||||
u8x8_y = 0;
|
||||
}
|
||||
|
||||
|
||||
void outChar(uint8_t c)
|
||||
{
|
||||
if ( u8x8_x >= u8x8_GetCols(&u8x8) )
|
||||
{
|
||||
u8x8_x = 0;
|
||||
u8x8_y++;
|
||||
}
|
||||
u8x8_DrawGlyph(&u8x8, u8x8_x, u8x8_y, c);
|
||||
u8x8_x++;
|
||||
}
|
||||
|
||||
void outStr(const char *s)
|
||||
{
|
||||
while( *s )
|
||||
outChar(*s++);
|
||||
}
|
||||
|
||||
void outHexHalfByte(uint8_t b)
|
||||
{
|
||||
b &= 0x0f;
|
||||
if ( b < 10 )
|
||||
outChar(b+'0');
|
||||
else
|
||||
outChar(b+'a'-10);
|
||||
}
|
||||
|
||||
void outHex8(uint8_t b)
|
||||
{
|
||||
outHexHalfByte(b >> 4);
|
||||
outHexHalfByte(b);
|
||||
}
|
||||
|
||||
void outHex16(uint16_t v)
|
||||
{
|
||||
outHex8(v>>8);
|
||||
outHex8(v);
|
||||
}
|
||||
|
||||
void outHex32(uint32_t v)
|
||||
{
|
||||
outHex16(v>>16);
|
||||
outHex16(v);
|
||||
}
|
||||
|
||||
void setRow(uint8_t r)
|
||||
{
|
||||
u8x8_x = 0;
|
||||
u8x8_y = r;
|
||||
}
|
||||
|
||||
|
||||
/*=======================================================================*/
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
setHSIClock(); /* enable 32 MHz Clock */
|
||||
startUp(); /* enable systick irq and several power regions */
|
||||
initDisplay(); /* aktivate display */
|
||||
|
||||
setRow(0); outStr("Hello World!");
|
||||
setRow(2); outStr("RCC_CSR:"); outHex32(RCC->CSR);
|
||||
setRow(3); outStr("PWR_CSR:"); outHex32(PWR->CSR);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
|
||||
stm32l031x6.ld
|
||||
|
||||
Modified for stm32l0 from the original nokeep.ld script from the
|
||||
arm-none-eabi examples by olikraus@gmail.com
|
||||
|
||||
Assuming, that the original nokeep.ld file is available under
|
||||
the GNU General Public License, this file is available under the
|
||||
same license.
|
||||
|
||||
There are three modifications:
|
||||
|
||||
1. Provide symbols for the stm32l0 startup code
|
||||
|
||||
The following symbols are required for the stm32l0 startup
|
||||
code (e.g. startup_stm32l031xx.s)
|
||||
|
||||
_sidata start address for the initialization values of the .data section
|
||||
_sdata start address for the .data section. defined in linker script
|
||||
_edata end address for the .data section. defined in linker script
|
||||
_sbss start address for the .bss section. defined in linker script
|
||||
_ebss end address for the .bss section. defined in linker script
|
||||
_estack top address of the stack
|
||||
|
||||
2. Stack size estimation / calculation
|
||||
|
||||
_Stack_Size has been added to allow better stack size calculation
|
||||
|
||||
3. KEEP keywords
|
||||
|
||||
Additionall KEEPs added for .init and .fini. Without this KEEP the
|
||||
generated code will not work, because of the missing _init function.
|
||||
|
||||
4. Bugfix: Allign the end of the flash area
|
||||
|
||||
*/
|
||||
|
||||
_Stack_Size = 0x400; /* stm32l0: estimated amount of stack */
|
||||
|
||||
|
||||
/* Linker script to configure memory regions.
|
||||
* Need modifying for a specific board.
|
||||
* FLASH.ORIGIN: starting address of flash
|
||||
* FLASH.LENGTH: length of flash
|
||||
* RAM.ORIGIN: starting address of RAM bank 0
|
||||
* RAM.LENGTH: length of RAM bank 0
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 32K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K
|
||||
}
|
||||
|
||||
/* Linker script to place sections and symbol values. Should be used together
|
||||
* with other linker script that defines memory regions FLASH and RAM.
|
||||
* It references following symbols, which must be defined in code:
|
||||
* Reset_Handler : Entry of reset handler
|
||||
*
|
||||
* It defines following symbols, which code can use without definition:
|
||||
* __exidx_start
|
||||
* __exidx_end
|
||||
* __copy_table_start__
|
||||
* __copy_table_end__
|
||||
* __zero_table_start__
|
||||
* __zero_table_end__
|
||||
* __etext
|
||||
* __data_start__
|
||||
* __preinit_array_start
|
||||
* __preinit_array_end
|
||||
* __init_array_start
|
||||
* __init_array_end
|
||||
* __fini_array_start
|
||||
* __fini_array_end
|
||||
* __data_end__
|
||||
* __bss_start__
|
||||
* __bss_end__
|
||||
* __end__
|
||||
* end
|
||||
* __HeapLimit
|
||||
* __StackLimit
|
||||
* __StackTop
|
||||
* __stack
|
||||
*/
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.isr_vector))
|
||||
*(.text*)
|
||||
|
||||
/* the st32l0 startup code calls __libc_init_array, which calls the _init */
|
||||
/* ... sooo.... better keep the init and fini sections */
|
||||
|
||||
KEEP ( *(.init) )
|
||||
KEEP ( *(.fini) )
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(.rodata*)
|
||||
|
||||
*(.eh_frame*)
|
||||
|
||||
/* allign the end of the flash area */
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} > FLASH
|
||||
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} > FLASH
|
||||
__exidx_end = .;
|
||||
|
||||
/* To copy multiple ROM to RAM sections,
|
||||
* uncomment .copy.table section and,
|
||||
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
|
||||
/*
|
||||
.copy.table :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__copy_table_start__ = .;
|
||||
LONG (__etext)
|
||||
LONG (__data_start__)
|
||||
LONG (__data_end__ - __data_start__)
|
||||
LONG (__etext2)
|
||||
LONG (__data2_start__)
|
||||
LONG (__data2_end__ - __data2_start__)
|
||||
__copy_table_end__ = .;
|
||||
} > FLASH
|
||||
*/
|
||||
|
||||
/* To clear multiple BSS sections,
|
||||
* uncomment .zero.table section and,
|
||||
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
|
||||
/*
|
||||
.zero.table :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__zero_table_start__ = .;
|
||||
LONG (__bss_start__)
|
||||
LONG (__bss_end__ - __bss_start__)
|
||||
LONG (__bss2_start__)
|
||||
LONG (__bss2_end__ - __bss2_start__)
|
||||
__zero_table_end__ = .;
|
||||
} > FLASH
|
||||
*/
|
||||
|
||||
__etext = .;
|
||||
_sidata = .; /* for stm32l0 startup code */
|
||||
|
||||
.data : AT (__etext)
|
||||
{
|
||||
__data_start__ = .;
|
||||
_sdata = .; /* for stm32l0 startup code */
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
*(.preinit_array)
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
*(SORT(.init_array.*))
|
||||
*(.init_array)
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
*(SORT(.fini_array.*))
|
||||
*(.fini_array)
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
*(.jcr)
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
_edata = .; /* for stm32l0 startup code */
|
||||
|
||||
} > RAM
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
_sbss = .; /* for stm32l0 startup code */
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
_ebss = .; /* for stm32l0 startup code */
|
||||
} > RAM
|
||||
|
||||
.heap (COPY):
|
||||
{
|
||||
__end__ = .;
|
||||
PROVIDE(end = .);
|
||||
*(.heap*)
|
||||
__HeapLimit = .;
|
||||
} > RAM
|
||||
|
||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||
* used for linker to calculate size of stack sections, and assign
|
||||
* values to stack symbols later */
|
||||
.stack_dummy (COPY):
|
||||
{
|
||||
*(.stack*)
|
||||
. = . + _Stack_Size; /* estimated stack size */
|
||||
} > RAM
|
||||
|
||||
/* Set stack top to end of RAM, and stack limit move down by
|
||||
* size of stack_dummy section */
|
||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_estack = __StackTop; /* for stm32l0 startup code */
|
||||
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||
PROVIDE(__stack = __StackTop);
|
||||
|
||||
/* Check if data + heap + stack exceeds RAM limit */
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||
}
|
||||
@@ -0,0 +1,965 @@
|
||||
/*
|
||||
|
||||
u8x8.h
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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.
|
||||
|
||||
|
||||
|
||||
U8glib has several layers. Each layer is implemented with a callback function.
|
||||
This callback function handels the messages for the layer.
|
||||
|
||||
The topmost level is the display layer. It includes the following messages:
|
||||
|
||||
U8X8_MSG_DISPLAY_SETUP_MEMORY no communicaation with the display, setup memory ony
|
||||
U8X8_MSG_DISPLAY_INIT
|
||||
U8X8_MSG_DISPLAY_SET_FLIP_MODE
|
||||
U8X8_MSG_DISPLAY_SET_POWER_SAVE
|
||||
U8X8_MSG_DISPLAY_SET_CONTRAST
|
||||
U8X8_MSG_DISPLAY_DRAW_TILE
|
||||
|
||||
A display driver may decided to breakdown these messages to a lower level interface or
|
||||
implement this functionality directly.
|
||||
|
||||
|
||||
One layer is the Command/Arg/Data interface. It can be used by the display layer
|
||||
to communicate with the display hardware.
|
||||
This layer only deals with data, commands and arguments. D/C line is unknown.
|
||||
U8X8_MSG_CAD_INIT
|
||||
U8X8_MSG_CAD_SET_I2C_ADR (obsolete)
|
||||
U8X8_MSG_CAD_SET_DEVICE (obsolete)
|
||||
U8X8_MSG_CAD_START_TRANSFER
|
||||
U8X8_MSG_CAD_SEND_CMD
|
||||
U8X8_MSG_CAD_SEND_ARG
|
||||
U8X8_MSG_CAD_SEND_DATA
|
||||
U8X8_MSG_CAD_END_TRANSFER
|
||||
|
||||
The byte interface is there to send 1 byte (8 bits) to the display hardware.
|
||||
This layer depends on the hardware of a microcontroller, if a specific hardware
|
||||
should be used (I2C or SPI).
|
||||
If this interface is implemented via software, it may use the GPIO level for sending
|
||||
bytes.
|
||||
U8X8_MSG_BYTE_INIT
|
||||
U8X8_MSG_BYTE_SEND 30
|
||||
U8X8_MSG_BYTE_SET_DC 31
|
||||
U8X8_MSG_BYTE_START_TRANSFER
|
||||
U8X8_MSG_BYTE_END_TRANSFER
|
||||
U8X8_MSG_BYTE_SET_I2C_ADR (obsolete)
|
||||
U8X8_MSG_BYTE_SET_DEVICE (obsolete)
|
||||
|
||||
GPIO and Delay
|
||||
U8X8_MSG_GPIO_INIT
|
||||
U8X8_MSG_DELAY_MILLI
|
||||
U8X8_MSG_DELAY_10MICRO
|
||||
U8X8_MSG_DELAY_100NANO
|
||||
U8X8_MSG_DELAY_NANO
|
||||
*/
|
||||
|
||||
#ifndef _U8X8_H
|
||||
#define _U8X8_H
|
||||
|
||||
/*==========================================*/
|
||||
/* Global Defines */
|
||||
|
||||
/* Undefine this to remove u8x8_SetContrast function */
|
||||
#define U8X8_WITH_SET_CONTRAST
|
||||
|
||||
/* Define this for an additional user pointer inside the u8x8 data struct */
|
||||
//#define U8X8_WITH_USER_PTR
|
||||
|
||||
|
||||
/* Undefine this to remove u8x8_SetFlipMode function */
|
||||
/* 26 May 2016: Obsolete */
|
||||
//#define U8X8_WITH_SET_FLIP_MODE
|
||||
|
||||
/* Select 0 or 1 for the default flip mode. This is not affected by U8X8_WITH_FLIP_MODE */
|
||||
/* Note: Not all display types support a mirror functon for the frame buffer */
|
||||
/* 26 May 2016: Obsolete */
|
||||
//#define U8X8_DEFAULT_FLIP_MODE 0
|
||||
|
||||
/*==========================================*/
|
||||
/* Includes */
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__GNUC__) && defined(__AVR__)
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
|
||||
/*==========================================*/
|
||||
/* C++ compatible */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* U8G2 internal defines */
|
||||
|
||||
/* the following macro returns the first value for the normal mode */
|
||||
/* or the second argument for the flip mode */
|
||||
|
||||
/* 26 May 2016: Obsolete
|
||||
#if U8X8_DEFAULT_FLIP_MODE == 0
|
||||
#define U8X8_IF_DEFAULT_NORMAL_OR_FLIP(normal, flipmode) (normal)
|
||||
#else
|
||||
#define U8X8_IF_DEFAULT_NORMAL_OR_FLIP(normal, flipmode) (flipmode)
|
||||
#endif
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define U8X8_NOINLINE __attribute__((noinline))
|
||||
# define U8X8_SECTION(name) __attribute__ ((section (name)))
|
||||
# define U8X8_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define U8X8_SECTION(name)
|
||||
# define U8X8_NOINLINE
|
||||
# define U8X8_UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && defined(__AVR__)
|
||||
# define U8X8_FONT_SECTION(name) U8X8_SECTION(".progmem." name)
|
||||
# define u8x8_pgm_read(adr) pgm_read_byte_near(adr)
|
||||
# define U8X8_PROGMEM PROGMEM
|
||||
#endif
|
||||
|
||||
#if defined(ESP8266)
|
||||
uint8_t u8x8_pgm_read_esp(const uint8_t * addr); /* u8x8_8x8.c */
|
||||
# define U8X8_FONT_SECTION(name) __attribute__((section(".text." name)))
|
||||
# define u8x8_pgm_read(adr) u8x8_pgm_read_esp(adr)
|
||||
# define U8X8_PROGMEM
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef U8X8_FONT_SECTION
|
||||
# define U8X8_FONT_SECTION(name)
|
||||
#endif
|
||||
|
||||
#ifndef u8x8_pgm_read
|
||||
# define u8x8_pgm_read(adr) (*(const uint8_t *)(adr))
|
||||
#endif
|
||||
|
||||
#ifndef U8X8_PROGMEM
|
||||
# define U8X8_PROGMEM
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO
|
||||
#define U8X8_USE_PINS
|
||||
#endif
|
||||
|
||||
/*==========================================*/
|
||||
/* U8X8 typedefs and data structures */
|
||||
|
||||
|
||||
typedef struct u8x8_struct u8x8_t;
|
||||
typedef struct u8x8_display_info_struct u8x8_display_info_t;
|
||||
typedef struct u8x8_tile_struct u8x8_tile_t;
|
||||
|
||||
typedef uint8_t (*u8x8_msg_cb)(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
typedef uint16_t (*u8x8_char_cb)(u8x8_t *u8x8, uint8_t b);
|
||||
|
||||
|
||||
|
||||
|
||||
//struct u8x8_mcd_struct
|
||||
//{
|
||||
// u8x8_msg_cb cb; /* current callback function */
|
||||
// u8x8_t *u8g2; /* pointer to the u8g2 parent to minimize the number of args */
|
||||
// u8x8_mcd_t *next;
|
||||
//};
|
||||
|
||||
struct u8x8_tile_struct
|
||||
{
|
||||
uint8_t *tile_ptr; /* pointer to one or more tiles... should be "const" */
|
||||
uint8_t cnt; /* number of tiles */
|
||||
uint8_t x_pos; /* tile x position */
|
||||
uint8_t y_pos; /* tile x position */
|
||||
};
|
||||
|
||||
|
||||
struct u8x8_display_info_struct
|
||||
{
|
||||
/* == general == */
|
||||
|
||||
uint8_t chip_enable_level; /* UC1601: 0 */
|
||||
uint8_t chip_disable_level; /* opposite of chip_enable_level */
|
||||
|
||||
uint8_t post_chip_enable_wait_ns; /* UC1601: 5ns */
|
||||
uint8_t pre_chip_disable_wait_ns; /* UC1601: 5ns */
|
||||
uint8_t reset_pulse_width_ms; /* UC1601: 0.003ms --> 1ms */
|
||||
uint8_t post_reset_wait_ms; /* UC1601: 6ms */
|
||||
|
||||
|
||||
/* == SPI interface == */
|
||||
|
||||
/* after SDA has been applied, wait this much time for the SCK data takeover edge */
|
||||
/* if this is smaller than sck_pulse_width_ns, then use the value from sck_pulse_width_ns */
|
||||
uint8_t sda_setup_time_ns; /* UC1601: 12ns */
|
||||
/* the pulse width of the the clock signal, cycle time is twice this value */
|
||||
/* max freq is 1/(2*sck_pulse_width_ns) */
|
||||
/* AVR: below 70: DIV2, 8 MHz, >= 70 --> 4MHz clock (DIV4) */
|
||||
uint8_t sck_pulse_width_ns; /* UC1701: 50ns */
|
||||
|
||||
/* until here we have 8 bytes (uint8_t). Newly introduced for SPI.beginTransaction */
|
||||
uint32_t sck_clock_hz;
|
||||
|
||||
/* previous name "sck_takeover_edge" renamed to "spi_mode" */
|
||||
/* bit 0 of spi_mode is equal to the value of the previous variable sck_takeover_edge, 20 Aug 16: This is wrong the bit is actually inverted */
|
||||
/* SPI has four clock modes: */
|
||||
/* 0: clock active high, data out on falling edge, clock default value is zero, takover on rising edge */
|
||||
/* 1: clock active high, data out on rising edge, clock default value is zero, takover on falling edge */
|
||||
/* 2: clock active low, data out on rising edge */
|
||||
/* 3: clock active low, data out on falling edge */
|
||||
/* most displays have clock mode 1 */
|
||||
uint8_t spi_mode;
|
||||
|
||||
/* == I2C == */
|
||||
uint8_t i2c_bus_clock_100kHz; /* UC1601: 1000000000/275 = 37 *100k */
|
||||
|
||||
|
||||
/* == 8 bit interface == */
|
||||
|
||||
/* how long to wait after all data line are set */
|
||||
uint8_t data_setup_time_ns; /* UC1601: 30ns */
|
||||
/* write enable pulse width */
|
||||
uint8_t write_pulse_width_ns; /* UC1601: 40ns */
|
||||
|
||||
/* == layout == */
|
||||
uint8_t tile_width;
|
||||
uint8_t tile_height;
|
||||
|
||||
uint8_t default_x_offset; /* default x offset for the display */
|
||||
uint8_t flipmode_x_offset; /* x offset, if flip mode is enabled */
|
||||
|
||||
/* pixel width is not used by the u8x8 procedures */
|
||||
/* instead it will be used by the u8g2 procedures, because the pixel dimension can */
|
||||
/* not always be calculated from the tile_width/_height */
|
||||
/* the following conditions must be true: */
|
||||
/* pixel_width <= tile_width*8 */
|
||||
/* pixel_height <= tile_height*8 */
|
||||
uint16_t pixel_width;
|
||||
uint16_t pixel_height;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* list of U8x8 pins */
|
||||
#define U8X8_PIN_D0 0
|
||||
#define U8X8_PIN_SPI_CLOCK 0
|
||||
#define U8X8_PIN_D1 1
|
||||
#define U8X8_PIN_SPI_DATA 1
|
||||
#define U8X8_PIN_D2 2
|
||||
#define U8X8_PIN_D3 3
|
||||
#define U8X8_PIN_D4 4
|
||||
#define U8X8_PIN_D5 5
|
||||
#define U8X8_PIN_D6 6
|
||||
#define U8X8_PIN_D7 7
|
||||
|
||||
#define U8X8_PIN_E 8
|
||||
#define U8X8_PIN_CS 9 /* parallel, SPI */
|
||||
#define U8X8_PIN_DC 10 /* parallel, SPI */
|
||||
#define U8X8_PIN_RESET 11 /* parallel, SPI, I2C */
|
||||
|
||||
#define U8X8_PIN_I2C_CLOCK 12 /* 1 = Input/high impedance, 0 = drive low */
|
||||
#define U8X8_PIN_I2C_DATA 13 /* 1 = Input/high impedance, 0 = drive low */
|
||||
|
||||
#define U8X8_PIN_CS1 14 /* KS0108 extra chip select */
|
||||
#define U8X8_PIN_CS2 15 /* KS0108 extra chip select */
|
||||
|
||||
#define U8X8_PIN_OUTPUT_CNT 16
|
||||
|
||||
#define U8X8_PIN_MENU_SELECT 16
|
||||
#define U8X8_PIN_MENU_NEXT 17
|
||||
#define U8X8_PIN_MENU_PREV 18
|
||||
#define U8X8_PIN_MENU_HOME 19
|
||||
#define U8X8_PIN_MENU_UP 20
|
||||
#define U8X8_PIN_MENU_DOWN 21
|
||||
|
||||
#define U8X8_PIN_INPUT_CNT 6
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
#define U8X8_PIN_CNT (U8X8_PIN_OUTPUT_CNT+U8X8_PIN_INPUT_CNT)
|
||||
#define U8X8_PIN_NONE 255
|
||||
#endif
|
||||
|
||||
struct u8x8_struct
|
||||
{
|
||||
const u8x8_display_info_t *display_info;
|
||||
u8x8_char_cb next_cb; /* procedure, which will be used to get the next char from the string */
|
||||
u8x8_msg_cb display_cb;
|
||||
u8x8_msg_cb cad_cb;
|
||||
u8x8_msg_cb byte_cb;
|
||||
u8x8_msg_cb gpio_and_delay_cb;
|
||||
const uint8_t *font;
|
||||
uint16_t encoding; /* encoding result for utf8 decoder in next_cb */
|
||||
uint8_t x_offset; /* copied from info struct, can be modified in flip mode */
|
||||
uint8_t is_font_inverse_mode; /* 0: normal, 1: font glyphs are inverted */
|
||||
uint8_t i2c_address; /* a valid i2c adr. Initially this is 255, but this is set to something usefull during DISPLAY_INIT */
|
||||
/* i2c_address is the address for writing data to the display */
|
||||
/* usually, the lowest bit must be zero for a valid address */
|
||||
uint8_t i2c_started; /* for i2c interface */
|
||||
uint8_t device_address; /* this is the device address, replacement for U8X8_MSG_CAD_SET_DEVICE */
|
||||
uint8_t utf8_state; /* number of chars which are still to scan */
|
||||
uint8_t gpio_result; /* return value from the gpio call (only for MENU keys at the moment) */
|
||||
uint8_t debounce_default_pin_state;
|
||||
uint8_t debounce_last_pin_state;
|
||||
uint8_t debounce_state;
|
||||
uint8_t debounce_result_msg; /* result msg or event after debounce */
|
||||
#ifdef U8X8_WITH_USER_PTR
|
||||
void *user_ptr;
|
||||
#endif
|
||||
#ifdef U8X8_USE_PINS
|
||||
uint8_t pins[U8X8_PIN_CNT]; /* defines a pinlist: Mainly a list of pins for the Arduino Envionment, use U8X8_PIN_xxx to access */
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef U8X8_WITH_USER_PTR
|
||||
#define u8x8_GetUserPtr(u8x8) ((u8x8)->user_ptr)
|
||||
#define u8x8_SetUserPtr(u8x8, p) ((u8x8)->user_ptr = (p))
|
||||
#endif
|
||||
|
||||
|
||||
#define u8x8_GetCols(u8x8) ((u8x8)->display_info->tile_width)
|
||||
#define u8x8_GetRows(u8x8) ((u8x8)->display_info->tile_height)
|
||||
#define u8x8_GetI2CAddress(u8x8) ((u8x8)->i2c_address)
|
||||
#define u8x8_SetI2CAddress(u8x8, address) ((u8x8)->i2c_address = (address))
|
||||
|
||||
#define u8x8_SetGPIOResult(u8x8, val) ((u8x8)->gpio_result = (val))
|
||||
#define u8x8_GetSPIClockPhase(u8x8) ((u8x8)->display_info->spi_mode & 0x01) /* 0 means rising edge */
|
||||
#define u8x8_GetSPIClockPolarity(u8x8) (((u8x8)->display_info->spi_mode & 0x02) >> 1)
|
||||
#define u8x8_GetSPIClockDefaultLevel(u8x8) (((u8x8)->display_info->spi_mode & 0x02) >> 1)
|
||||
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
#define u8x8_SetPin(u8x8,pin,val) (u8x8)->pins[pin] = (val)
|
||||
#define u8x8_SetMenuSelectPin(u8x8, val) u8x8_SetPin((u8x8),U8X8_PIN_MENU_SELECT,(val))
|
||||
#define u8x8_SetMenuNextPin(u8x8, val) u8x8_SetPin((u8x8),U8X8_PIN_MENU_NEXT,(val))
|
||||
#define u8x8_SetMenuPrevPin(u8x8, val) u8x8_SetPin((u8x8),U8X8_PIN_MENU_PREV,(val))
|
||||
#define u8x8_SetMenuHomePin(u8x8, val) u8x8_SetPin((u8x8),U8X8_PIN_MENU_HOME,(val))
|
||||
#define u8x8_SetMenuUpPin(u8x8, val) u8x8_SetPin((u8x8),U8X8_PIN_MENU_UP,(val))
|
||||
#define u8x8_SetMenuDownPin(u8x8, val) u8x8_SetPin((u8x8),U8X8_PIN_MENU_DOWN,(val))
|
||||
#endif
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
|
||||
/* helper functions */
|
||||
void u8x8_d_helper_display_setup_memory(u8x8_t *u8x8, const u8x8_display_info_t *display_info);
|
||||
void u8x8_d_helper_display_init(u8x8_t *u8g2);
|
||||
|
||||
/* Display Interface */
|
||||
|
||||
/*
|
||||
Name: U8X8_MSG_DISPLAY_SETUP_MEMORY
|
||||
Args: None
|
||||
Tasks:
|
||||
1) setup u8g2->display_info
|
||||
copy u8g2->display_info->default_x_offset to u8g2->x_offset
|
||||
|
||||
usually calls u8x8_d_helper_display_setup_memory()
|
||||
*/
|
||||
#define U8X8_MSG_DISPLAY_SETUP_MEMORY 9
|
||||
|
||||
/*
|
||||
Name: U8X8_MSG_DISPLAY_INIT
|
||||
Args: None
|
||||
Tasks:
|
||||
|
||||
2) put interface into default state:
|
||||
execute u8x8_gpio_Init for port directions
|
||||
execute u8x8_cad_Init for default port levels
|
||||
3) set CS status (not clear, may be done in cad/byte interface
|
||||
4) execute display reset (gpio interface)
|
||||
5) send setup sequence to display, do not activate display, disable "power save" will follow
|
||||
*/
|
||||
#define U8X8_MSG_DISPLAY_INIT 10
|
||||
|
||||
/*
|
||||
Name: U8X8_MSG_DISPLAY_SET_POWER_SAVE
|
||||
Args: arg_int: 0: normal mode (RAM is visible on the display), 1: nothing is shown
|
||||
Tasks:
|
||||
Depending on arg_int, put the display into normal or power save mode.
|
||||
Send the corresponding sequence to the display.
|
||||
In power save mode, it must be possible to modify the RAM content.
|
||||
*/
|
||||
#define U8X8_MSG_DISPLAY_SET_POWER_SAVE 11
|
||||
|
||||
/*
|
||||
Name: U8X8_MSG_DISPLAY_SET_FLIP_MODE
|
||||
Args: arg_int: 0: normal mode, 1: flipped HW screen (180 degree)
|
||||
Tasks:
|
||||
Reprogramms the display controller to rotate the display by
|
||||
180 degree (arg_int = 1) or not (arg_int = 0)
|
||||
This may change u8g2->x_offset if the display is smaller than the controller ram
|
||||
This message should only be supported if U8X8_WITH_FLIP_MODE is defined.
|
||||
*/
|
||||
#define U8X8_MSG_DISPLAY_SET_FLIP_MODE 13
|
||||
|
||||
/* arg_int: 0..255 contrast value */
|
||||
#define U8X8_MSG_DISPLAY_SET_CONTRAST 14
|
||||
|
||||
/*
|
||||
Name: U8X8_MSG_DISPLAY_DRAW_TILE
|
||||
Args:
|
||||
arg_int: How often to repeat this tile pattern
|
||||
arg_ptr: pointer to u8x8_tile_t
|
||||
uint8_t *tile_ptr; pointer to one or more tiles (number is "cnt")
|
||||
uint8_t cnt; number of tiles
|
||||
uint8_t x_pos; first tile x position
|
||||
uint8_t y_pos; first tile y position
|
||||
Tasks:
|
||||
One tile has exactly 8 bytes (8x8 pixel monochrome bitmap).
|
||||
The lowest bit of the first byte is the upper left corner
|
||||
The highest bit of the first byte is the lower left corner
|
||||
The lowest bit of the last byte is the upper right corner
|
||||
The highest bit of the last byte is the lower left corner
|
||||
"tile_ptr" is the address of a memory area, which contains
|
||||
one or more tiles. "cnt" will contain the exact number of
|
||||
tiles in the memory areay. The size of the memory area is 8*cnt;
|
||||
Multiple tiles in the memory area form a horizontal sequence, this
|
||||
means the first tile is drawn at x_pos/y_pos, the second tile is drawn
|
||||
at x_pos+1/y_pos, third at x_pos+2/y_pos.
|
||||
"arg_int" tells how often the tile sequence should be repeated:
|
||||
For example if "cnt" is two and tile_ptr points to tiles A and B,
|
||||
then for arg_int = 3, the following tile sequence will be drawn:
|
||||
ABABAB. Totally, cnt*arg_int tiles will be drawn.
|
||||
|
||||
*/
|
||||
#define U8X8_MSG_DISPLAY_DRAW_TILE 15
|
||||
|
||||
|
||||
/*
|
||||
Name: U8X8_MSG_DISPLAY_REFRESH
|
||||
Args:
|
||||
arg_int: -
|
||||
arg_ptr: -
|
||||
|
||||
This was introduced for the SSD1606 eInk display.
|
||||
The problem is, that all RAM access will not appear on the screen
|
||||
unless a special command is executed. With this message, this command
|
||||
sequence is executed.
|
||||
Use
|
||||
void u8x8_RefreshDisplay(u8x8_t *u8x8)
|
||||
to send the message to the display handler.
|
||||
*/
|
||||
#define U8X8_MSG_DISPLAY_REFRESH 16
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_setup.c */
|
||||
|
||||
/*
|
||||
Setup u8x8 object itself. This should be the very first function
|
||||
called on the new u8x8 object. After this call, assign the callback
|
||||
functions. Optional: Set the pins
|
||||
*/
|
||||
|
||||
void u8x8_SetupDefaults(u8x8_t *u8x8); /* do not use this, use u8x8_Setup() instead */
|
||||
|
||||
void u8x8_Setup(u8x8_t *u8x8, u8x8_msg_cb display_cb, u8x8_msg_cb cad_cb, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_display.c */
|
||||
uint8_t u8x8_DrawTile(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr);
|
||||
|
||||
/*
|
||||
After a call to u8x8_SetupDefaults,
|
||||
setup u8x8 memory structures & inform callbacks
|
||||
This function is also called from u8x8_Setup(), so do not call u8x8_SetupMemory()
|
||||
directly, but use u8x8_Setup() instead.
|
||||
*/
|
||||
void u8x8_SetupMemory(u8x8_t *u8x8);
|
||||
|
||||
/*
|
||||
After calling u8x8_SetupMemory()/u8x8_Setup(), init the display hardware itself.
|
||||
This will will the first time, u8x8 talks to the display.
|
||||
It will init the display, but keep display in power save mode.
|
||||
Usually this command must be followed by u8x8_SetPowerSave()
|
||||
*/
|
||||
void u8x8_InitDisplay(u8x8_t *u8x8);
|
||||
/* wake up display from power save mode */
|
||||
void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable);
|
||||
void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode);
|
||||
void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value);
|
||||
void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf) U8X8_NOINLINE;
|
||||
void u8x8_ClearDisplay(u8x8_t *u8x8); // this does not work for u8g2 in some cases
|
||||
void u8x8_FillDisplay(u8x8_t *u8x8);
|
||||
void u8x8_RefreshDisplay(u8x8_t *u8x8); // make RAM content visible on the display (Dec 16: SSD1606 only)
|
||||
void u8x8_ClearLine(u8x8_t *u8x8, uint8_t line);
|
||||
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* Command Arg Data (CAD) Interface */
|
||||
|
||||
/*
|
||||
U8X8_MSG_CAD_INIT
|
||||
no args
|
||||
call U8X8_MSG_BYTE_INIT
|
||||
setup default values for the I/O lines
|
||||
*/
|
||||
#define U8X8_MSG_CAD_INIT 20
|
||||
|
||||
|
||||
#define U8X8_MSG_CAD_SEND_CMD 21
|
||||
/* arg_int: cmd byte */
|
||||
#define U8X8_MSG_CAD_SEND_ARG 22
|
||||
/* arg_int: arg byte */
|
||||
#define U8X8_MSG_CAD_SEND_DATA 23
|
||||
/* arg_int: expected cs level after processing this msg */
|
||||
#define U8X8_MSG_CAD_START_TRANSFER 24
|
||||
/* arg_int: expected cs level after processing this msg */
|
||||
#define U8X8_MSG_CAD_END_TRANSFER 25
|
||||
/* arg_int = 0: disable chip, arg_int = 1: enable chip */
|
||||
//#define U8X8_MSG_CAD_SET_I2C_ADR 26
|
||||
//#define U8X8_MSG_CAD_SET_DEVICE 27
|
||||
|
||||
|
||||
|
||||
/* u8g_cad.c */
|
||||
|
||||
#define u8x8_cad_Init(u8x8) ((u8x8)->cad_cb((u8x8), U8X8_MSG_CAD_INIT, 0, NULL ))
|
||||
|
||||
uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd) U8X8_NOINLINE;
|
||||
uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg) U8X8_NOINLINE;
|
||||
uint8_t u8x8_cad_SendMultipleArg(u8x8_t *u8x8, uint8_t cnt, uint8_t arg) U8X8_NOINLINE;
|
||||
uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data) U8X8_NOINLINE;
|
||||
uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8) U8X8_NOINLINE;
|
||||
uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8) U8X8_NOINLINE;
|
||||
|
||||
/*
|
||||
#define U8X8_C(c0) (0x04), (c0)
|
||||
#define U8X8_CA(c0,a0) (0x05), (c0), (a0)
|
||||
#define U8X8_CAA(c0,a0,a1) (0x06), (c0), (a0), (a1)
|
||||
#define U8X8_DATA() (0x10)
|
||||
#define U8X8_D1(d0) (0x11), (d0)
|
||||
*/
|
||||
|
||||
#define U8X8_C(c0) (U8X8_MSG_CAD_SEND_CMD), (c0)
|
||||
#define U8X8_A(a0) (U8X8_MSG_CAD_SEND_ARG), (a0)
|
||||
#define U8X8_CA(c0,a0) (U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0)
|
||||
#define U8X8_CAA(c0,a0,a1) (U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1)
|
||||
#define U8X8_CAAAA(c0,a0,a1,a2,a3) (U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1), (U8X8_MSG_CAD_SEND_ARG), (a2), (U8X8_MSG_CAD_SEND_ARG), (a3)
|
||||
#define U8X8_AAC(a0,a1,c0) (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1), (U8X8_MSG_CAD_SEND_CMD), (c0)
|
||||
#define U8X8_D1(d0) (U8X8_MSG_CAD_SEND_DATA), (d0)
|
||||
|
||||
#define U8X8_A4(a0,a1,a2,a3) U8X8_A(a0), U8X8_A(a1), U8X8_A(a2), U8X8_A(a3)
|
||||
#define U8X8_A8(a0,a1,a2,a3,a4,a5,a6,a7) U8X8_A4((a0), (a1), (a2), (a3)), U8X8_A4((a4), (a5), (a6), (a7))
|
||||
|
||||
|
||||
#define U8X8_START_TRANSFER() (U8X8_MSG_CAD_START_TRANSFER)
|
||||
#define U8X8_END_TRANSFER() (U8X8_MSG_CAD_END_TRANSFER)
|
||||
#define U8X8_DLY(m) (0xfe),(m) /* delay in milli seconds */
|
||||
#define U8X8_END() (0xff)
|
||||
|
||||
void u8x8_cad_SendSequence(u8x8_t *u8x8, uint8_t const *data);
|
||||
uint8_t u8x8_cad_empty(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_110(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_001(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_011(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_st7920_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_st75256_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_ld7032_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_cad_uc16xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* Byte Interface */
|
||||
|
||||
#define U8X8_MSG_BYTE_INIT U8X8_MSG_CAD_INIT
|
||||
#define U8X8_MSG_BYTE_SET_DC 32
|
||||
|
||||
#define U8X8_MSG_BYTE_SEND U8X8_MSG_CAD_SEND_DATA
|
||||
|
||||
#define U8X8_MSG_BYTE_START_TRANSFER U8X8_MSG_CAD_START_TRANSFER
|
||||
#define U8X8_MSG_BYTE_END_TRANSFER U8X8_MSG_CAD_END_TRANSFER
|
||||
|
||||
//#define U8X8_MSG_BYTE_SET_I2C_ADR U8X8_MSG_CAD_SET_I2C_ADR
|
||||
//#define U8X8_MSG_BYTE_SET_DEVICE U8X8_MSG_CAD_SET_DEVICE
|
||||
|
||||
|
||||
uint8_t u8x8_byte_SetDC(u8x8_t *u8x8, uint8_t dc) U8X8_NOINLINE;
|
||||
uint8_t u8x8_byte_SendByte(u8x8_t *u8x8, uint8_t byte) U8X8_NOINLINE;
|
||||
uint8_t u8x8_byte_SendBytes(u8x8_t *u8x8, uint8_t cnt, uint8_t *data) U8X8_NOINLINE;
|
||||
uint8_t u8x8_byte_StartTransfer(u8x8_t *u8x8);
|
||||
uint8_t u8x8_byte_EndTransfer(u8x8_t *u8x8);
|
||||
|
||||
uint8_t u8x8_byte_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_byte_8bit_6800mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_byte_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_byte_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
/* uint8_t u8x8_byte_st7920_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); */
|
||||
void u8x8_byte_set_ks0108_cs(u8x8_t *u8x8, uint8_t arg) U8X8_NOINLINE;
|
||||
uint8_t u8x8_byte_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_byte_ssd13xx_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* OBSOLETE! */
|
||||
uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_byte_sed1520(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* GPIO Interface */
|
||||
|
||||
|
||||
/*
|
||||
U8X8_MSG_GPIO_AND_DELAY_INIT
|
||||
no args
|
||||
setup port directions, do not set IO levels, this is done with BYTE/CAD_INIT
|
||||
*/
|
||||
#define U8X8_MSG_GPIO_AND_DELAY_INIT 40
|
||||
|
||||
/* arg_int: milliseconds */
|
||||
#define U8X8_MSG_DELAY_MILLI 41
|
||||
|
||||
/* 10MICRO and 100NANO are not used at the moment */
|
||||
#define U8X8_MSG_DELAY_10MICRO 42
|
||||
#define U8X8_MSG_DELAY_100NANO 43
|
||||
|
||||
|
||||
#define U8X8_MSG_DELAY_NANO 44
|
||||
/* delay of one i2c unit, should be 5us for 100K, and 1.25us for 400K */
|
||||
#define U8X8_MSG_DELAY_I2C 45
|
||||
|
||||
#define U8X8_MSG_GPIO(x) (64+(x))
|
||||
#ifdef U8X8_USE_PINS
|
||||
#define u8x8_GetPinIndex(u8x8, msg) ((msg)&0x3f)
|
||||
#define u8x8_GetPinValue(u8x8, msg) ((u8x8)->pins[(msg)&0x3f])
|
||||
#endif
|
||||
|
||||
#define U8X8_MSG_GPIO_D0 U8X8_MSG_GPIO(U8X8_PIN_D0)
|
||||
#define U8X8_MSG_GPIO_SPI_CLOCK U8X8_MSG_GPIO(U8X8_PIN_SPI_CLOCK)
|
||||
#define U8X8_MSG_GPIO_D1 U8X8_MSG_GPIO(U8X8_PIN_D1)
|
||||
#define U8X8_MSG_GPIO_SPI_DATA U8X8_MSG_GPIO(U8X8_PIN_SPI_DATA)
|
||||
#define U8X8_MSG_GPIO_D2 U8X8_MSG_GPIO(U8X8_PIN_D2)
|
||||
#define U8X8_MSG_GPIO_D3 U8X8_MSG_GPIO(U8X8_PIN_D3)
|
||||
#define U8X8_MSG_GPIO_D4 U8X8_MSG_GPIO(U8X8_PIN_D4)
|
||||
#define U8X8_MSG_GPIO_D5 U8X8_MSG_GPIO(U8X8_PIN_D5)
|
||||
#define U8X8_MSG_GPIO_D6 U8X8_MSG_GPIO(U8X8_PIN_D6)
|
||||
#define U8X8_MSG_GPIO_D7 U8X8_MSG_GPIO(U8X8_PIN_D7)
|
||||
#define U8X8_MSG_GPIO_E U8X8_MSG_GPIO(U8X8_PIN_E) // used as E1 for the SED1520
|
||||
#define U8X8_MSG_GPIO_CS U8X8_MSG_GPIO(U8X8_PIN_CS) // used as E2 for the SED1520
|
||||
#define U8X8_MSG_GPIO_DC U8X8_MSG_GPIO(U8X8_PIN_DC)
|
||||
#define U8X8_MSG_GPIO_RESET U8X8_MSG_GPIO(U8X8_PIN_RESET)
|
||||
#define U8X8_MSG_GPIO_I2C_CLOCK U8X8_MSG_GPIO(U8X8_PIN_I2C_CLOCK)
|
||||
#define U8X8_MSG_GPIO_I2C_DATA U8X8_MSG_GPIO(U8X8_PIN_I2C_DATA)
|
||||
|
||||
|
||||
#define U8X8_MSG_GPIO_CS1 U8X8_MSG_GPIO(U8X8_PIN_CS1) /* KS0108 extra chip select */
|
||||
#define U8X8_MSG_GPIO_CS2 U8X8_MSG_GPIO(U8X8_PIN_CS2) /* KS0108 extra chip select */
|
||||
|
||||
|
||||
/* these message expect the return value in u8x8->gpio_result */
|
||||
#define U8X8_MSG_GPIO_MENU_SELECT U8X8_MSG_GPIO(U8X8_PIN_MENU_SELECT)
|
||||
#define U8X8_MSG_GPIO_MENU_NEXT U8X8_MSG_GPIO(U8X8_PIN_MENU_NEXT)
|
||||
#define U8X8_MSG_GPIO_MENU_PREV U8X8_MSG_GPIO(U8X8_PIN_MENU_PREV)
|
||||
#define U8X8_MSG_GPIO_MENU_HOME U8X8_MSG_GPIO(U8X8_PIN_MENU_HOME)
|
||||
#define U8X8_MSG_GPIO_MENU_UP U8X8_MSG_GPIO(U8X8_PIN_MENU_UP)
|
||||
#define U8X8_MSG_GPIO_MENU_DOWN U8X8_MSG_GPIO(U8X8_PIN_MENU_DOWN)
|
||||
|
||||
|
||||
#define u8x8_gpio_Init(u8x8) ((u8x8)->gpio_and_delay_cb((u8x8), U8X8_MSG_GPIO_AND_DELAY_INIT, 0, NULL ))
|
||||
|
||||
|
||||
/*
|
||||
#define u8x8_gpio_SetDC(u8x8, v) ((u8x8)->gpio_and_delay_cb((u8x8), U8X8_MSG_GPIO_DC, (v), NULL ))
|
||||
#define u8x8_gpio_SetCS(u8x8, v) ((u8x8)->gpio_and_delay_cb((u8x8), U8X8_MSG_GPIO_CS, (v), NULL ))
|
||||
#define u8x8_gpio_SetReset(u8x8, v) ((u8x8)->gpio_and_delay_cb((u8x8), U8X8_MSG_GPIO_RESET, (v), NULL ))
|
||||
*/
|
||||
|
||||
#define u8x8_gpio_SetDC(u8x8, v) u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_DC, (v))
|
||||
#define u8x8_gpio_SetCS(u8x8, v) u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS, (v))
|
||||
#define u8x8_gpio_SetReset(u8x8, v) u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_RESET, (v))
|
||||
#define u8x8_gpio_SetSPIClock(u8x8, v) u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_SPI_CLOCK, (v))
|
||||
#define u8x8_gpio_SetSPIData(u8x8, v) u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_SPI_DATA, (v))
|
||||
#define u8x8_gpio_SetI2CClock(u8x8, v) u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_I2C_CLOCK, (v))
|
||||
#define u8x8_gpio_SetI2CData(u8x8, v) u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_I2C_DATA, (v))
|
||||
|
||||
void u8x8_gpio_call(u8x8_t *u8x8, uint8_t msg, uint8_t arg) U8X8_NOINLINE;
|
||||
|
||||
#define u8x8_gpio_Delay(u8x8, msg, dly) u8x8_gpio_call((u8x8), (msg), (dly))
|
||||
//void u8x8_gpio_Delay(u8x8_t *u8x8, uint8_t msg, uint8_t dly) U8X8_NOINLINE;
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_debounce.c */
|
||||
/* return U8X8_MSG_GPIO_MENU_xxxxx messages */
|
||||
uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8);
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_d_stdio.c */
|
||||
void u8x8_SetupStdio(u8x8_t *u8x8);
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_d_sdl_128x64.c */
|
||||
void u8x8_Setup_SDL_128x64(u8x8_t *u8x8);
|
||||
void u8x8_Setup_SDL_240x160(u8x8_t *u8x8);
|
||||
int u8g_sdl_get_key(void);
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_d_tga.c */
|
||||
void u8x8_Setup_TGA_DESC(u8x8_t *u8x8);
|
||||
void u8x8_Setup_TGA_LCD(u8x8_t *u8x8);
|
||||
void tga_save(const char *name);
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_d_bitmap.c */
|
||||
uint8_t u8x8_GetBitmapPixel(u8x8_t *u8x8, uint16_t x, uint16_t y);
|
||||
void u8x8_SaveBitmapTGA(u8x8_t *u8x8, const char *filename);
|
||||
void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t pixel_width, uint16_t pixel_height);
|
||||
uint8_t u8x8_ConnectBitmapToU8x8(u8x8_t *u8x8);
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_d_utf8.c */
|
||||
void u8x8_Setup_Utf8(u8x8_t *u8x8); /* stdout UTF-8 display */
|
||||
void utf8_show(void); /* show content of UTF-8 frame buffer */
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_d_XXX.c */
|
||||
uint8_t u8x8_d_uc1701_ea_dogs102(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1701_mini12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1305_128x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1306_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1306_128x64_alt0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1309_128x64_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1309_128x64_noname2(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_sh1106_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_sh1106_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_sh1106_128x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7920_192x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7920_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1306_128x32_univision(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1306_64x48_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1306_64x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1306_64x32_1f(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1306_96x16_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ls013b7dh03_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7565_ea_dogm128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7565_64128n(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7565_ea_dogm132(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7565_zolen_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7565_nhd_c12832(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7565_nhd_c12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7565_lm6059(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7565_erc12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7567_pi_132x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7567_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st7588_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st75256_jlx256128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st75256_jlx25664(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_st75256_jlx172104(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_nt7534_tg12864r(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* u8x8_d_st7565.c */
|
||||
uint8_t u8x8_d_ld7032_60x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_t6963_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_t6963_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_t6963_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_t6963_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1322_nhd_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_a2printer_384x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_sed1330_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ra8835_nhd_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ra8835_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1325_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1327_seeed_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1327_midas_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1326_er_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1329_128x96_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1601_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1604_jlx19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1608_erc24064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1608_erc240120(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1608_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1610_ea_dogxl160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1611_ea_dogm240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1611_ea_dogxl240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1611_ew50850(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* 240x160 */
|
||||
uint8_t u8x8_d_uc1617_jlx128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_uc1638_160x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ks0108_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ks0108_erm19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_sbn1661_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_sed1520_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_pcd8544_84x48(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_pcf8812_96x65(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1606_172x72(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1607_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ssd1607_v2_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_il3820_296x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_il3820_v2_296x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_lc7981_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_lc7981_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_lc7981_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_ist3020_erc19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_d_max7219_32x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_8x8.c */
|
||||
|
||||
uint16_t u8x8_upscale_byte(uint8_t x) U8X8_NOINLINE;
|
||||
|
||||
|
||||
void u8x8_utf8_init(u8x8_t *u8x8);
|
||||
uint16_t u8x8_ascii_next(u8x8_t *u8x8, uint8_t b);
|
||||
uint16_t u8x8_utf8_next(u8x8_t *u8x8, uint8_t b);
|
||||
// the following two functions are replaced by the init/next functions
|
||||
//uint16_t u8x8_get_encoding_from_utf8_string(const char **str);
|
||||
//uint16_t u8x8_get_char_from_string(const char **str);
|
||||
|
||||
void u8x8_SetFont(u8x8_t *u8x8, const uint8_t *font_8x8);
|
||||
void u8x8_DrawGlyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding);
|
||||
void u8x8_Draw2x2Glyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding);
|
||||
uint8_t u8x8_DrawString(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s);
|
||||
uint8_t u8x8_DrawUTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s); /* return number of glyps */
|
||||
uint8_t u8x8_Draw2x2String(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s);
|
||||
uint8_t u8x8_Draw2x2UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s);
|
||||
uint8_t u8x8_GetUTF8Len(u8x8_t *u8x8, const char *s);
|
||||
#define u8x8_SetInverseFont(u8x8, b) (u8x8)->is_font_inverse_mode = (b)
|
||||
|
||||
/*==========================================*/
|
||||
/* itoa procedures */
|
||||
const char *u8x8_u8toa(uint8_t v, uint8_t d);
|
||||
const char *u8x8_u16toa(uint16_t v, uint8_t d);
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* u8x8_string.c */
|
||||
|
||||
uint8_t u8x8_GetStringLineCnt(const char *str); /* return 0 for str==NULL */
|
||||
const char *u8x8_GetStringLineStart(uint8_t line_idx, const char *str );
|
||||
void u8x8_CopyStringLine(char *dest, uint8_t line_idx, const char *str);
|
||||
/* draw one line, consider \t for center */
|
||||
uint8_t u8x8_DrawUTF8Line(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s);
|
||||
/* draw multiple lines, handle \t */
|
||||
uint8_t u8x8_DrawUTF8Lines(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s);
|
||||
|
||||
/*==========================================*/
|
||||
|
||||
/* u8x8_selection_list.c */
|
||||
struct _u8sl_struct
|
||||
{
|
||||
uint8_t visible; /* number of visible elements in the menu */
|
||||
uint8_t total; /* total number of elements in the menu */
|
||||
uint8_t first_pos; /* position of the first visible line */
|
||||
uint8_t current_pos; /* current cursor position, starts at 0 */
|
||||
|
||||
uint8_t x; /* u8x8 only, not used in u8g2 */
|
||||
uint8_t y; /* u8x8 only, not used in u8g2 */
|
||||
};
|
||||
typedef struct _u8sl_struct u8sl_t;
|
||||
|
||||
typedef void (*u8x8_sl_cb)(u8x8_t *u8x8, u8sl_t *u8sl, uint8_t idx, const void *aux);
|
||||
|
||||
void u8sl_Next(u8sl_t *u8sl);
|
||||
void u8sl_Prev(u8sl_t *u8sl);
|
||||
|
||||
uint8_t u8x8_UserInterfaceSelectionList(u8x8_t *u8x8, const char *title, uint8_t start_pos, const char *sl);
|
||||
|
||||
/*==========================================*/
|
||||
|
||||
/* u8x8_message.c */
|
||||
uint8_t u8x8_UserInterfaceMessage(u8x8_t *u8x8, const char *title1, const char *title2, const char *title3, const char *buttons);
|
||||
|
||||
/*==========================================*/
|
||||
|
||||
/* u8x8_input_value.c */
|
||||
|
||||
uint8_t u8x8_UserInterfaceInputValue(u8x8_t *u8x8, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post);
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* start font list */
|
||||
extern const uint8_t u8x8_font_amstrad_cpc_extended_f[] U8X8_FONT_SECTION("u8x8_font_amstrad_cpc_extended_f");
|
||||
extern const uint8_t u8x8_font_amstrad_cpc_extended_r[] U8X8_FONT_SECTION("u8x8_font_amstrad_cpc_extended_r");
|
||||
extern const uint8_t u8x8_font_amstrad_cpc_extended_n[] U8X8_FONT_SECTION("u8x8_font_amstrad_cpc_extended_n");
|
||||
extern const uint8_t u8x8_font_amstrad_cpc_extended_u[] U8X8_FONT_SECTION("u8x8_font_amstrad_cpc_extended_u");
|
||||
extern const uint8_t u8x8_font_5x7_f[] U8X8_FONT_SECTION("u8x8_font_5x7_f");
|
||||
extern const uint8_t u8x8_font_5x7_r[] U8X8_FONT_SECTION("u8x8_font_5x7_r");
|
||||
extern const uint8_t u8x8_font_5x7_n[] U8X8_FONT_SECTION("u8x8_font_5x7_n");
|
||||
extern const uint8_t u8x8_font_5x8_f[] U8X8_FONT_SECTION("u8x8_font_5x8_f");
|
||||
extern const uint8_t u8x8_font_5x8_r[] U8X8_FONT_SECTION("u8x8_font_5x8_r");
|
||||
extern const uint8_t u8x8_font_5x8_n[] U8X8_FONT_SECTION("u8x8_font_5x8_n");
|
||||
extern const uint8_t u8x8_font_artossans8_r[] U8X8_FONT_SECTION("u8x8_font_artossans8_r");
|
||||
extern const uint8_t u8x8_font_artossans8_n[] U8X8_FONT_SECTION("u8x8_font_artossans8_n");
|
||||
extern const uint8_t u8x8_font_artossans8_u[] U8X8_FONT_SECTION("u8x8_font_artossans8_u");
|
||||
extern const uint8_t u8x8_font_artosserif8_r[] U8X8_FONT_SECTION("u8x8_font_artosserif8_r");
|
||||
extern const uint8_t u8x8_font_artosserif8_n[] U8X8_FONT_SECTION("u8x8_font_artosserif8_n");
|
||||
extern const uint8_t u8x8_font_artosserif8_u[] U8X8_FONT_SECTION("u8x8_font_artosserif8_u");
|
||||
extern const uint8_t u8x8_font_chroma48medium8_r[] U8X8_FONT_SECTION("u8x8_font_chroma48medium8_r");
|
||||
extern const uint8_t u8x8_font_chroma48medium8_n[] U8X8_FONT_SECTION("u8x8_font_chroma48medium8_n");
|
||||
extern const uint8_t u8x8_font_chroma48medium8_u[] U8X8_FONT_SECTION("u8x8_font_chroma48medium8_u");
|
||||
extern const uint8_t u8x8_font_saikyosansbold8_n[] U8X8_FONT_SECTION("u8x8_font_saikyosansbold8_n");
|
||||
extern const uint8_t u8x8_font_saikyosansbold8_u[] U8X8_FONT_SECTION("u8x8_font_saikyosansbold8_u");
|
||||
extern const uint8_t u8x8_font_torussansbold8_r[] U8X8_FONT_SECTION("u8x8_font_torussansbold8_r");
|
||||
extern const uint8_t u8x8_font_torussansbold8_n[] U8X8_FONT_SECTION("u8x8_font_torussansbold8_n");
|
||||
extern const uint8_t u8x8_font_torussansbold8_u[] U8X8_FONT_SECTION("u8x8_font_torussansbold8_u");
|
||||
extern const uint8_t u8x8_font_victoriabold8_r[] U8X8_FONT_SECTION("u8x8_font_victoriabold8_r");
|
||||
extern const uint8_t u8x8_font_victoriabold8_n[] U8X8_FONT_SECTION("u8x8_font_victoriabold8_n");
|
||||
extern const uint8_t u8x8_font_victoriabold8_u[] U8X8_FONT_SECTION("u8x8_font_victoriabold8_u");
|
||||
extern const uint8_t u8x8_font_victoriamedium8_r[] U8X8_FONT_SECTION("u8x8_font_victoriamedium8_r");
|
||||
extern const uint8_t u8x8_font_victoriamedium8_n[] U8X8_FONT_SECTION("u8x8_font_victoriamedium8_n");
|
||||
extern const uint8_t u8x8_font_victoriamedium8_u[] U8X8_FONT_SECTION("u8x8_font_victoriamedium8_u");
|
||||
extern const uint8_t u8x8_font_pressstart2p_f[] U8X8_FONT_SECTION("u8x8_font_pressstart2p_f");
|
||||
extern const uint8_t u8x8_font_pressstart2p_r[] U8X8_FONT_SECTION("u8x8_font_pressstart2p_r");
|
||||
extern const uint8_t u8x8_font_pressstart2p_n[] U8X8_FONT_SECTION("u8x8_font_pressstart2p_n");
|
||||
extern const uint8_t u8x8_font_pressstart2p_u[] U8X8_FONT_SECTION("u8x8_font_pressstart2p_u");
|
||||
extern const uint8_t u8x8_font_pcsenior_f[] U8X8_FONT_SECTION("u8x8_font_pcsenior_f");
|
||||
extern const uint8_t u8x8_font_pcsenior_r[] U8X8_FONT_SECTION("u8x8_font_pcsenior_r");
|
||||
extern const uint8_t u8x8_font_pcsenior_n[] U8X8_FONT_SECTION("u8x8_font_pcsenior_n");
|
||||
extern const uint8_t u8x8_font_pcsenior_u[] U8X8_FONT_SECTION("u8x8_font_pcsenior_u");
|
||||
extern const uint8_t u8x8_font_pxplusibmcgathin_f[] U8X8_FONT_SECTION("u8x8_font_pxplusibmcgathin_f");
|
||||
extern const uint8_t u8x8_font_pxplusibmcgathin_r[] U8X8_FONT_SECTION("u8x8_font_pxplusibmcgathin_r");
|
||||
extern const uint8_t u8x8_font_pxplusibmcgathin_n[] U8X8_FONT_SECTION("u8x8_font_pxplusibmcgathin_n");
|
||||
extern const uint8_t u8x8_font_pxplusibmcgathin_u[] U8X8_FONT_SECTION("u8x8_font_pxplusibmcgathin_u");
|
||||
extern const uint8_t u8x8_font_pxplusibmcga_f[] U8X8_FONT_SECTION("u8x8_font_pxplusibmcga_f");
|
||||
extern const uint8_t u8x8_font_pxplusibmcga_r[] U8X8_FONT_SECTION("u8x8_font_pxplusibmcga_r");
|
||||
extern const uint8_t u8x8_font_pxplusibmcga_n[] U8X8_FONT_SECTION("u8x8_font_pxplusibmcga_n");
|
||||
extern const uint8_t u8x8_font_pxplusibmcga_u[] U8X8_FONT_SECTION("u8x8_font_pxplusibmcga_u");
|
||||
extern const uint8_t u8x8_font_pxplustandynewtv_f[] U8X8_FONT_SECTION("u8x8_font_pxplustandynewtv_f");
|
||||
extern const uint8_t u8x8_font_pxplustandynewtv_r[] U8X8_FONT_SECTION("u8x8_font_pxplustandynewtv_r");
|
||||
extern const uint8_t u8x8_font_pxplustandynewtv_n[] U8X8_FONT_SECTION("u8x8_font_pxplustandynewtv_n");
|
||||
extern const uint8_t u8x8_font_pxplustandynewtv_u[] U8X8_FONT_SECTION("u8x8_font_pxplustandynewtv_u");
|
||||
|
||||
/* end font list */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _U8X8_H */
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
/*
|
||||
|
||||
u8x8_8x8.c
|
||||
|
||||
font procedures, directly interfaces display procedures
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
#if defined(ESP8266)
|
||||
uint8_t u8x8_pgm_read_esp(const uint8_t * addr)
|
||||
{
|
||||
uint32_t bytes;
|
||||
bytes = *(uint32_t*)((uint32_t)addr & ~3);
|
||||
return ((uint8_t*)&bytes)[(uint32_t)addr & 3];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void u8x8_SetFont(u8x8_t *u8x8, const uint8_t *font_8x8)
|
||||
{
|
||||
u8x8->font = font_8x8;
|
||||
}
|
||||
|
||||
/*
|
||||
Args:
|
||||
u8x8: ptr to u8x8 structure
|
||||
encoding: glyph for which the data is requested (must be between 0 and 255)
|
||||
buf: pointer to 8 bytes
|
||||
*/
|
||||
static void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf) U8X8_NOINLINE;
|
||||
static void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf)
|
||||
{
|
||||
uint8_t first, last, i;
|
||||
uint16_t offset;
|
||||
first = u8x8_pgm_read(u8x8->font+0);
|
||||
last = u8x8_pgm_read(u8x8->font+1);
|
||||
|
||||
/* get the glyph bitmap from the font */
|
||||
if ( first <= encoding && encoding <= last )
|
||||
{
|
||||
offset = encoding;
|
||||
offset -= first;
|
||||
offset *= 8;
|
||||
offset +=2;
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
buf[i] = u8x8_pgm_read(u8x8->font+offset);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
buf[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* invert the bitmap if required */
|
||||
if ( u8x8->is_font_inverse_mode )
|
||||
{
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
buf[i] ^= 255;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void u8x8_DrawGlyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
u8x8_get_glyph_data(u8x8, encoding, buf);
|
||||
u8x8_DrawTile(u8x8, x, y, 1, buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Source: http://graphics.stanford.edu/~seander/bithacks.html
|
||||
Section: Interleave bits by Binary Magic Numbers
|
||||
Original codes is here:
|
||||
static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF};
|
||||
static const unsigned int S[] = {1, 2, 4, 8};
|
||||
|
||||
unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x
|
||||
unsigned int y; // are in the even positions and bits from y in the odd;
|
||||
unsigned int z; // z gets the resulting 32-bit Morton Number.
|
||||
// x and y must initially be less than 65536.
|
||||
|
||||
x = (x | (x << S[3])) & B[3];
|
||||
x = (x | (x << S[2])) & B[2];
|
||||
x = (x | (x << S[1])) & B[1];
|
||||
x = (x | (x << S[0])) & B[0];
|
||||
|
||||
y = (y | (y << S[3])) & B[3];
|
||||
y = (y | (y << S[2])) & B[2];
|
||||
y = (y | (y << S[1])) & B[1];
|
||||
y = (y | (y << S[0])) & B[0];
|
||||
|
||||
z = x | (y << 1);
|
||||
*/
|
||||
uint16_t u8x8_upscale_byte(uint8_t x)
|
||||
{
|
||||
uint16_t y = x;
|
||||
y |= (y << 4); // x = (x | (x << S[2])) & B[2];
|
||||
y &= 0x0f0f;
|
||||
y |= (y << 2); // x = (x | (x << S[1])) & B[1];
|
||||
y &= 0x3333;
|
||||
y |= (y << 1); // x = (x | (x << S[0])) & B[0];
|
||||
y &= 0x5555;
|
||||
|
||||
y |= (y << 1); // z = x | (y << 1);
|
||||
return y;
|
||||
}
|
||||
|
||||
static void u8x8_upscale_buf(uint8_t *src, uint8_t *dest) U8X8_NOINLINE;
|
||||
static void u8x8_upscale_buf(uint8_t *src, uint8_t *dest)
|
||||
{
|
||||
uint8_t i = 4;
|
||||
do
|
||||
{
|
||||
*dest++ = *src;
|
||||
*dest++ = *src++;
|
||||
i--;
|
||||
} while( i > 0 );
|
||||
}
|
||||
|
||||
void u8x8_Draw2x2Glyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t t;
|
||||
uint8_t buf[8];
|
||||
uint8_t buf1[8];
|
||||
uint8_t buf2[8];
|
||||
u8x8_get_glyph_data(u8x8, encoding, buf);
|
||||
for( i = 0; i < 8; i ++ )
|
||||
{
|
||||
t = u8x8_upscale_byte(buf[i]);
|
||||
buf1[i] = t >> 8;
|
||||
buf2[i] = t & 255;
|
||||
}
|
||||
u8x8_upscale_buf(buf2, buf);
|
||||
u8x8_DrawTile(u8x8, x, y, 1, buf);
|
||||
|
||||
u8x8_upscale_buf(buf2+4, buf);
|
||||
u8x8_DrawTile(u8x8, x+1, y, 1, buf);
|
||||
|
||||
u8x8_upscale_buf(buf1, buf);
|
||||
u8x8_DrawTile(u8x8, x, y+1, 1, buf);
|
||||
|
||||
u8x8_upscale_buf(buf1+4, buf);
|
||||
u8x8_DrawTile(u8x8, x+1, y+1, 1, buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
source: https://en.wikipedia.org/wiki/UTF-8
|
||||
Bits from to bytes Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
|
||||
7 U+0000 U+007F 1 0xxxxxxx
|
||||
11 U+0080 U+07FF 2 110xxxxx 10xxxxxx
|
||||
16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
|
||||
21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/* reset the internal state machine */
|
||||
void u8x8_utf8_init(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8->utf8_state = 0; /* also reset during u8x8_SetupDefaults() */
|
||||
}
|
||||
|
||||
uint16_t u8x8_ascii_next(U8X8_UNUSED u8x8_t *u8x8, uint8_t b)
|
||||
{
|
||||
if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */
|
||||
return 0x0ffff; /* end of string detected*/
|
||||
return b;
|
||||
}
|
||||
|
||||
/*
|
||||
pass a byte from an utf8 encoded string to the utf8 decoder state machine
|
||||
returns
|
||||
0x0fffe: no glyph, just continue
|
||||
0x0ffff: end of string
|
||||
anything else: The decoded encoding
|
||||
*/
|
||||
uint16_t u8x8_utf8_next(u8x8_t *u8x8, uint8_t b)
|
||||
{
|
||||
if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */
|
||||
return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
|
||||
if ( u8x8->utf8_state == 0 )
|
||||
{
|
||||
if ( b >= 0xfc ) /* 6 byte sequence */
|
||||
{
|
||||
u8x8->utf8_state = 5;
|
||||
b &= 1;
|
||||
}
|
||||
else if ( b >= 0xf8 )
|
||||
{
|
||||
u8x8->utf8_state = 4;
|
||||
b &= 3;
|
||||
}
|
||||
else if ( b >= 0xf0 )
|
||||
{
|
||||
u8x8->utf8_state = 3;
|
||||
b &= 7;
|
||||
}
|
||||
else if ( b >= 0xe0 )
|
||||
{
|
||||
u8x8->utf8_state = 2;
|
||||
b &= 15;
|
||||
}
|
||||
else if ( b >= 0xc0 )
|
||||
{
|
||||
u8x8->utf8_state = 1;
|
||||
b &= 0x01f;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* do nothing, just use the value as encoding */
|
||||
return b;
|
||||
}
|
||||
u8x8->encoding = b;
|
||||
return 0x0fffe;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8->utf8_state--;
|
||||
/* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
|
||||
u8x8->encoding<<=6;
|
||||
b &= 0x03f;
|
||||
u8x8->encoding |= b;
|
||||
if ( u8x8->utf8_state != 0 )
|
||||
return 0x0fffe; /* nothing to do yet */
|
||||
}
|
||||
return u8x8->encoding;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
|
||||
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||
{
|
||||
uint16_t e;
|
||||
uint8_t cnt = 0;
|
||||
u8x8_utf8_init(u8x8);
|
||||
for(;;)
|
||||
{
|
||||
e = u8x8->next_cb(u8x8, (uint8_t)*s);
|
||||
if ( e == 0x0ffff )
|
||||
break;
|
||||
s++;
|
||||
if ( e != 0x0fffe )
|
||||
{
|
||||
u8x8_DrawGlyph(u8x8, x, y, e);
|
||||
x++;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
uint8_t u8x8_DrawString(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||
{
|
||||
u8x8->next_cb = u8x8_ascii_next;
|
||||
return u8x8_draw_string(u8x8, x, y, s);
|
||||
}
|
||||
|
||||
uint8_t u8x8_DrawUTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||
{
|
||||
u8x8->next_cb = u8x8_utf8_next;
|
||||
return u8x8_draw_string(u8x8, x, y, s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_draw_2x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
|
||||
static uint8_t u8x8_draw_2x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||
{
|
||||
uint16_t e;
|
||||
uint8_t cnt = 0;
|
||||
u8x8_utf8_init(u8x8);
|
||||
for(;;)
|
||||
{
|
||||
e = u8x8->next_cb(u8x8, (uint8_t)*s);
|
||||
if ( e == 0x0ffff )
|
||||
break;
|
||||
s++;
|
||||
if ( e != 0x0fffe )
|
||||
{
|
||||
u8x8_Draw2x2Glyph(u8x8, x, y, e);
|
||||
x+=2;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
uint8_t u8x8_Draw2x2String(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||
{
|
||||
u8x8->next_cb = u8x8_ascii_next;
|
||||
return u8x8_draw_2x2_string(u8x8, x, y, s);
|
||||
}
|
||||
|
||||
uint8_t u8x8_Draw2x2UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
|
||||
{
|
||||
u8x8->next_cb = u8x8_utf8_next;
|
||||
return u8x8_draw_2x2_string(u8x8, x, y, s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t u8x8_GetUTF8Len(u8x8_t *u8x8, const char *s)
|
||||
{
|
||||
uint16_t e;
|
||||
uint8_t cnt = 0;
|
||||
u8x8_utf8_init(u8x8);
|
||||
for(;;)
|
||||
{
|
||||
e = u8x8_utf8_next(u8x8, *s);
|
||||
if ( e == 0x0ffff )
|
||||
break;
|
||||
s++;
|
||||
if ( e != 0x0fffe )
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,653 @@
|
||||
/*
|
||||
|
||||
u8x8_byte.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
uint8_t u8x8_byte_SetDC(u8x8_t *u8x8, uint8_t dc)
|
||||
{
|
||||
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SET_DC, dc, NULL);
|
||||
}
|
||||
|
||||
uint8_t u8x8_byte_SendBytes(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
|
||||
{
|
||||
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SEND, cnt, (void *)data);
|
||||
}
|
||||
|
||||
uint8_t u8x8_byte_SendByte(u8x8_t *u8x8, uint8_t byte)
|
||||
{
|
||||
return u8x8_byte_SendBytes(u8x8, 1, &byte);
|
||||
}
|
||||
|
||||
uint8_t u8x8_byte_StartTransfer(u8x8_t *u8x8)
|
||||
{
|
||||
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_START_TRANSFER, 0, NULL);
|
||||
}
|
||||
|
||||
uint8_t u8x8_byte_EndTransfer(u8x8_t *u8x8)
|
||||
{
|
||||
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_END_TRANSFER, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Uses:
|
||||
u8x8->display_info->sda_setup_time_ns
|
||||
u8x8->display_info->sck_pulse_width_ns
|
||||
u8x8->display_info->spi_mode
|
||||
u8x8->display_info->chip_disable_level
|
||||
u8x8->display_info->chip_enable_level
|
||||
u8x8->display_info->post_chip_enable_wait_ns
|
||||
u8x8->display_info->pre_chip_disable_wait_ns
|
||||
Calls to GPIO and DELAY:
|
||||
U8X8_MSG_DELAY_NANO
|
||||
U8X8_MSG_GPIO_DC
|
||||
U8X8_MSG_GPIO_CS
|
||||
U8X8_MSG_GPIO_CLOCK
|
||||
U8X8_MSG_GPIO_DATA
|
||||
Handles:
|
||||
U8X8_MSG_BYTE_INIT
|
||||
U8X8_MSG_BYTE_SEND
|
||||
U8X8_MSG_BYTE_SET_DC
|
||||
U8X8_MSG_BYTE_START_TRANSFER
|
||||
U8X8_MSG_BYTE_END_TRANSFER
|
||||
*/
|
||||
|
||||
uint8_t u8x8_byte_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t i, b;
|
||||
uint8_t *data;
|
||||
uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
|
||||
uint8_t not_takeover_edge = 1 - takeover_edge;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
b = *data;
|
||||
data++;
|
||||
arg_int--;
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
if ( b & 128 )
|
||||
u8x8_gpio_SetSPIData(u8x8, 1);
|
||||
else
|
||||
u8x8_gpio_SetSPIData(u8x8, 0);
|
||||
b <<= 1;
|
||||
|
||||
u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
|
||||
u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
/* disable chipselect */
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
/* no wait required here */
|
||||
|
||||
/* for SPI: setup correct level of the clock signal */
|
||||
u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=========================================*/
|
||||
|
||||
uint8_t u8x8_byte_8bit_6800mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t i, b;
|
||||
uint8_t *data;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
b = *data;
|
||||
data++;
|
||||
arg_int--;
|
||||
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
|
||||
{
|
||||
u8x8_gpio_call(u8x8, i, b&1);
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
/* disable chipselect */
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
/* ensure that the enable signal is high */
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8x8_byte_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t i, b;
|
||||
uint8_t *data;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
b = *data;
|
||||
data++;
|
||||
arg_int--;
|
||||
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
|
||||
{
|
||||
u8x8_gpio_call(u8x8, i, b&1);
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
/* disable chipselect */
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
/* ensure that the enable signal is high */
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=========================================*/
|
||||
|
||||
uint8_t u8x8_byte_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t *data;
|
||||
uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
|
||||
uint8_t not_takeover_edge = 1 - takeover_edge;
|
||||
uint16_t b;
|
||||
static uint8_t last_dc;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
b = *data;
|
||||
if ( last_dc != 0 )
|
||||
b |= 256;
|
||||
data++;
|
||||
arg_int--;
|
||||
for( i = 0; i < 9; i++ )
|
||||
{
|
||||
if ( b & 256 )
|
||||
u8x8_gpio_SetSPIData(u8x8, 1);
|
||||
else
|
||||
u8x8_gpio_SetSPIData(u8x8, 0);
|
||||
b <<= 1;
|
||||
|
||||
u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
|
||||
u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
/* disable chipselect */
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
/* no wait required here */
|
||||
|
||||
/* for SPI: setup correct level of the clock signal */
|
||||
u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
last_dc = arg_int;
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=========================================*/
|
||||
|
||||
void u8x8_byte_set_ks0108_cs(u8x8_t *u8x8, uint8_t arg)
|
||||
{
|
||||
u8x8_gpio_SetCS(u8x8, arg&1);
|
||||
arg = arg >> 1;
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS1, arg&1);
|
||||
arg = arg >> 2;
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS2, arg&1);
|
||||
}
|
||||
|
||||
/* 6800 mode */
|
||||
uint8_t u8x8_byte_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t i, b;
|
||||
uint8_t *data;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
b = *data;
|
||||
data++;
|
||||
arg_int--;
|
||||
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
|
||||
{
|
||||
u8x8_gpio_call(u8x8, i, b&1);
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
/* disable chipselect */
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
/* ensure that the enable signal is low */
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
/* expects 3 bits in arg_int for the chip select lines */
|
||||
u8x8_byte_set_ks0108_cs(u8x8, arg_int);
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
|
||||
u8x8_byte_set_ks0108_cs(u8x8, arg_int);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* sed1520 or sbn1661
|
||||
U8X8_MSG_GPIO_E --> E1
|
||||
U8X8_MSG_GPIO_CS --> E2
|
||||
*/
|
||||
uint8_t u8x8_byte_sed1520(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t i, b;
|
||||
uint8_t *data;
|
||||
static uint8_t enable_pin;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
b = *data;
|
||||
data++;
|
||||
arg_int--;
|
||||
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
|
||||
{
|
||||
u8x8_gpio_call(u8x8, i, b&1);
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
|
||||
u8x8_gpio_call(u8x8, enable_pin, 1);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
|
||||
u8x8_gpio_call(u8x8, enable_pin, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
/* disable chipselect */
|
||||
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
/* ensure that the enable signals are low */
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS, 0);
|
||||
enable_pin = U8X8_MSG_GPIO_E;
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
/* cs lines are not supported for the SED1520/SBN1661 */
|
||||
/* instead, this will select the E1 or E2 line */
|
||||
enable_pin = U8X8_MSG_GPIO_E;
|
||||
if ( arg_int != 0 )
|
||||
enable_pin = U8X8_MSG_GPIO_CS;
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=========================================*/
|
||||
|
||||
|
||||
/*
|
||||
software i2c,
|
||||
ignores ACK response (which is anyway not provided by some displays)
|
||||
also does not allow reading from the device
|
||||
*/
|
||||
static void i2c_delay(u8x8_t *u8x8) U8X8_NOINLINE;
|
||||
static void i2c_delay(u8x8_t *u8x8)
|
||||
{
|
||||
//u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_10MICRO, u8x8->display_info->i2c_bus_clock_100kHz);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_I2C, u8x8->display_info->i2c_bus_clock_100kHz);
|
||||
}
|
||||
|
||||
static void i2c_init(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8_gpio_SetI2CClock(u8x8, 1);
|
||||
u8x8_gpio_SetI2CData(u8x8, 1);
|
||||
|
||||
i2c_delay(u8x8);
|
||||
}
|
||||
|
||||
/* actually, the scl line is not observed, so this procedure does not return a value */
|
||||
|
||||
static void i2c_read_scl_and_delay(u8x8_t *u8x8)
|
||||
{
|
||||
/* set as input (line will be high) */
|
||||
u8x8_gpio_SetI2CClock(u8x8, 1);
|
||||
|
||||
i2c_delay(u8x8);
|
||||
}
|
||||
|
||||
static void i2c_clear_scl(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8_gpio_SetI2CClock(u8x8, 0);
|
||||
}
|
||||
|
||||
static void i2c_read_sda(u8x8_t *u8x8)
|
||||
{
|
||||
/* set as input (line will be high) */
|
||||
u8x8_gpio_SetI2CData(u8x8, 1);
|
||||
}
|
||||
|
||||
static void i2c_clear_sda(u8x8_t *u8x8)
|
||||
{
|
||||
/* set open collector and drive low */
|
||||
u8x8_gpio_SetI2CData(u8x8, 0);
|
||||
}
|
||||
|
||||
static void i2c_start(u8x8_t *u8x8)
|
||||
{
|
||||
if ( u8x8->i2c_started != 0 )
|
||||
{
|
||||
/* if already started: do restart */
|
||||
i2c_read_sda(u8x8); /* SDA = 1 */
|
||||
i2c_delay(u8x8);
|
||||
i2c_read_scl_and_delay(u8x8);
|
||||
}
|
||||
i2c_read_sda(u8x8);
|
||||
/* send the start condition, both lines go from 1 to 0 */
|
||||
i2c_clear_sda(u8x8);
|
||||
i2c_delay(u8x8);
|
||||
i2c_clear_scl(u8x8);
|
||||
u8x8->i2c_started = 1;
|
||||
}
|
||||
|
||||
|
||||
static void i2c_stop(u8x8_t *u8x8)
|
||||
{
|
||||
/* set SDA to 0 */
|
||||
i2c_clear_sda(u8x8);
|
||||
i2c_delay(u8x8);
|
||||
|
||||
/* now release all lines */
|
||||
i2c_read_scl_and_delay(u8x8);
|
||||
|
||||
/* set SDA to 1 */
|
||||
i2c_read_sda(u8x8);
|
||||
i2c_delay(u8x8);
|
||||
u8x8->i2c_started = 0;
|
||||
}
|
||||
|
||||
static void i2c_write_bit(u8x8_t *u8x8, uint8_t val)
|
||||
{
|
||||
if (val)
|
||||
i2c_read_sda(u8x8);
|
||||
else
|
||||
i2c_clear_sda(u8x8);
|
||||
|
||||
i2c_delay(u8x8);
|
||||
i2c_read_scl_and_delay(u8x8);
|
||||
i2c_clear_scl(u8x8);
|
||||
}
|
||||
|
||||
static void i2c_read_bit(u8x8_t *u8x8)
|
||||
{
|
||||
//uint8_t val;
|
||||
/* do not drive SDA */
|
||||
i2c_read_sda(u8x8);
|
||||
i2c_delay(u8x8);
|
||||
i2c_read_scl_and_delay(u8x8);
|
||||
i2c_read_sda(u8x8);
|
||||
i2c_delay(u8x8);
|
||||
i2c_clear_scl(u8x8);
|
||||
//return val;
|
||||
}
|
||||
|
||||
static void i2c_write_byte(u8x8_t *u8x8, uint8_t b)
|
||||
{
|
||||
i2c_write_bit(u8x8, b & 128);
|
||||
i2c_write_bit(u8x8, b & 64);
|
||||
i2c_write_bit(u8x8, b & 32);
|
||||
i2c_write_bit(u8x8, b & 16);
|
||||
i2c_write_bit(u8x8, b & 8);
|
||||
i2c_write_bit(u8x8, b & 4);
|
||||
i2c_write_bit(u8x8, b & 2);
|
||||
i2c_write_bit(u8x8, b & 1);
|
||||
|
||||
/* read ack from client */
|
||||
/* 0: ack was given by client */
|
||||
/* 1: nothing happend during ack cycle */
|
||||
i2c_read_bit(u8x8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef OBSOLETE_HANDLED_BY_CAD_PROCEDURE
|
||||
uint8_t u8x8_byte_ssd13xx_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t *data;
|
||||
static uint8_t last_dc = 0;
|
||||
static uint8_t is_send_dc = 0; /* instruction, whether i2c-start including dc has to be sent */
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
|
||||
if ( is_send_dc != 0 )
|
||||
{
|
||||
|
||||
i2c_start(u8x8);
|
||||
i2c_write_byte(u8x8, 0x078); /* write slave adr and read/write bit */
|
||||
|
||||
if ( last_dc == 0 )
|
||||
i2c_write_byte(u8x8, 0);
|
||||
else
|
||||
i2c_write_byte(u8x8, 0x040);
|
||||
is_send_dc = 0;
|
||||
}
|
||||
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
i2c_write_byte(u8x8, *data);
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
i2c_init(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
if ( last_dc != arg_int )
|
||||
{
|
||||
last_dc = arg_int;
|
||||
is_send_dc = 1;
|
||||
}
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
last_dc = 0;
|
||||
is_send_dc = 1;
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
i2c_stop(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t *data;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
i2c_write_byte(u8x8, *data);
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
i2c_init(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
i2c_start(u8x8);
|
||||
i2c_write_byte(u8x8, u8x8_GetI2CAddress(u8x8));
|
||||
//i2c_write_byte(u8x8, 0x078);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
i2c_stop(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
|
||||
u8x8_cad.c
|
||||
|
||||
"command arg data" interface to the graphics controller
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, olikraus@gmail.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
The following sequence must be used for any data, which is set to the display:
|
||||
|
||||
|
||||
uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8)
|
||||
|
||||
any of the following calls
|
||||
uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd)
|
||||
uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg)
|
||||
uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
|
||||
|
||||
uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8)
|
||||
|
||||
|
||||
|
||||
*/
|
||||
/*
|
||||
uint8_t u8x8_cad_template(u8x8_t *u8x8, uint8_t msg, uint16_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
u8x8_mcd_byte_SetDC(mcd->next, 1);
|
||||
u8x8_mcd_byte_Send(mcd->next, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_mcd_byte_SetDC(mcd->next, 1);
|
||||
u8x8_mcd_byte_Send(mcd->next, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
u8x8_mcd_byte_SetDC(mcd->next, 0);
|
||||
for( i = 0; i < 8; i++ )
|
||||
u8x8_mcd_byte_Send(mcd->next, ((uint8_t *)arg_ptr)[i]);
|
||||
break;
|
||||
case U8X8_MSG_CAD_RESET:
|
||||
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd)
|
||||
{
|
||||
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_CMD, cmd, NULL);
|
||||
}
|
||||
|
||||
uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg)
|
||||
{
|
||||
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL);
|
||||
}
|
||||
|
||||
uint8_t u8x8_cad_SendMultipleArg(u8x8_t *u8x8, uint8_t cnt, uint8_t arg)
|
||||
{
|
||||
while( cnt > 0 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL);
|
||||
cnt--;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
|
||||
{
|
||||
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, cnt, data);
|
||||
}
|
||||
|
||||
uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8)
|
||||
{
|
||||
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
|
||||
}
|
||||
|
||||
uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8)
|
||||
{
|
||||
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
21 c send command c
|
||||
22 a send arg a
|
||||
23 d send data d
|
||||
24 CS on
|
||||
25 CS off
|
||||
254 milli delay by milliseconds
|
||||
255 end of sequence
|
||||
*/
|
||||
|
||||
void u8x8_cad_SendSequence(u8x8_t *u8x8, uint8_t const *data)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint8_t v;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
cmd = *data;
|
||||
data++;
|
||||
switch( cmd )
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
v = *data;
|
||||
u8x8->cad_cb(u8x8, cmd, v, NULL);
|
||||
data++;
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
v = *data;
|
||||
u8x8_cad_SendData(u8x8, 1, &v);
|
||||
data++;
|
||||
break;
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
u8x8->cad_cb(u8x8, cmd, 0, NULL);
|
||||
break;
|
||||
case 0x0fe:
|
||||
v = *data;
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, v);
|
||||
data++;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t u8x8_cad_empty(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
convert to bytes by using
|
||||
dc = 1 for commands and args and
|
||||
dc = 0 for data
|
||||
*/
|
||||
uint8_t u8x8_cad_110(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
u8x8_byte_SetDC(u8x8, 1);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_byte_SetDC(u8x8, 1);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
u8x8_byte_SetDC(u8x8, 0);
|
||||
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
|
||||
//break;
|
||||
/* fall through */
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
convert to bytes by using
|
||||
dc = 1 for commands and args and
|
||||
dc = 0 for data
|
||||
t6963
|
||||
*/
|
||||
uint8_t u8x8_cad_100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
u8x8_byte_SetDC(u8x8, 1);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_byte_SetDC(u8x8, 0);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
u8x8_byte_SetDC(u8x8, 0);
|
||||
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
|
||||
//break;
|
||||
/* fall through */
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
convert to bytes by using
|
||||
dc = 0 for commands and args and
|
||||
dc = 1 for data
|
||||
*/
|
||||
uint8_t u8x8_cad_001(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
u8x8_byte_SetDC(u8x8, 0);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_byte_SetDC(u8x8, 0);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
u8x8_byte_SetDC(u8x8, 1);
|
||||
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
|
||||
//break;
|
||||
/* fall through */
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
convert to bytes by using
|
||||
dc = 0 for commands
|
||||
dc = 1 for args and data
|
||||
*/
|
||||
uint8_t u8x8_cad_011(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
u8x8_byte_SetDC(u8x8, 0);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_byte_SetDC(u8x8, 1);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
u8x8_byte_SetDC(u8x8, 1);
|
||||
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
|
||||
//break;
|
||||
/* fall through */
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* cad procedure for the ST7920 in SPI mode */
|
||||
/* u8x8_byte_SetDC is not used */
|
||||
uint8_t u8x8_cad_st7920_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t *data;
|
||||
uint8_t b;
|
||||
uint8_t i;
|
||||
static uint8_t buf[16];
|
||||
uint8_t *ptr;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
u8x8_byte_SendByte(u8x8, 0x0f8);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||
u8x8_byte_SendByte(u8x8, arg_int & 0x0f0);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||
u8x8_byte_SendByte(u8x8, arg_int << 4);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_byte_SendByte(u8x8, 0x0f8);
|
||||
u8x8_byte_SendByte(u8x8, arg_int & 0x0f0);
|
||||
u8x8_byte_SendByte(u8x8, arg_int << 4);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
|
||||
u8x8_byte_SendByte(u8x8, 0x0fa);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||
|
||||
/* this loop should be optimized: multiple bytes should be sent */
|
||||
/* u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr); */
|
||||
data = (uint8_t *)arg_ptr;
|
||||
|
||||
/* the following loop increases speed by 20% */
|
||||
while( arg_int >= 8 )
|
||||
{
|
||||
i = 8;
|
||||
ptr = buf;
|
||||
do
|
||||
{
|
||||
b = *data++;
|
||||
*ptr++= b & 0x0f0;
|
||||
b <<= 4;
|
||||
*ptr++= b;
|
||||
i--;
|
||||
} while( i > 0 );
|
||||
arg_int -= 8;
|
||||
u8x8_byte_SendBytes(u8x8, 16, buf);
|
||||
}
|
||||
|
||||
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
b = *data;
|
||||
u8x8_byte_SendByte(u8x8, b & 0x0f0);
|
||||
u8x8_byte_SendByte(u8x8, b << 4);
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
|
||||
break;
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* cad procedure for the SSD13xx family in I2C mode */
|
||||
/* this procedure is also used by the ST7588 */
|
||||
/* u8x8_byte_SetDC is not used */
|
||||
/* U8X8_MSG_BYTE_START_TRANSFER starts i2c transfer, U8X8_MSG_BYTE_END_TRANSFER stops transfer */
|
||||
/* After transfer start, a full byte indicates command or data mode */
|
||||
|
||||
static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
|
||||
static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
u8x8_byte_SendByte(u8x8, 0x040);
|
||||
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, arg_ptr);
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
}
|
||||
|
||||
uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t *p;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
/* 7 Nov 2016: Can this be improved? */
|
||||
//u8x8_byte_SetDC(u8x8, 0);
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
//u8x8_byte_SendByte(u8x8, u8x8_GetI2CAddress(u8x8));
|
||||
u8x8_byte_SendByte(u8x8, 0x000);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
//u8x8_byte_SetDC(u8x8, 1);
|
||||
|
||||
/* the FeatherWing OLED with the 32u4 transfer of long byte */
|
||||
/* streams was not possible. This is broken down to */
|
||||
/* smaller streams, 32 seems to be the limit... */
|
||||
/* I guess this is related to the size of the Wire buffers in Arduino */
|
||||
/* Unfortunately, this can not be handled in the byte level drivers, */
|
||||
/* so this is done here. Even further, only 24 bytes will be sent, */
|
||||
/* because there will be another byte (DC) required during the transfer */
|
||||
p = arg_ptr;
|
||||
while( arg_int > 24 )
|
||||
{
|
||||
u8x8_i2c_data_transfer(u8x8, 24, p);
|
||||
arg_int-=24;
|
||||
p+=24;
|
||||
}
|
||||
u8x8_i2c_data_transfer(u8x8, arg_int, p);
|
||||
break;
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||
if ( u8x8->i2c_address == 255 )
|
||||
u8x8->i2c_address = 0x078;
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
/* cad transfer commands are ignored */
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* the st75256 i2c driver is a copy of the ssd13xx driver, but with arg=1 */
|
||||
/* modified from cad001 (ssd13xx) to cad011 */
|
||||
uint8_t u8x8_cad_st75256_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t *p;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
u8x8_byte_SendByte(u8x8, 0x000);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
u8x8_byte_SendByte(u8x8, 0x040);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
/* see ssd13xx driver */
|
||||
p = arg_ptr;
|
||||
while( arg_int > 24 )
|
||||
{
|
||||
u8x8_i2c_data_transfer(u8x8, 24, p);
|
||||
arg_int-=24;
|
||||
p+=24;
|
||||
}
|
||||
u8x8_i2c_data_transfer(u8x8, arg_int, p);
|
||||
break;
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||
if ( u8x8->i2c_address == 255 )
|
||||
u8x8->i2c_address = 0x078; /* ST75256, often this is 0x07e */
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
/* cad transfer commands are ignored */
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* cad i2c procedure for the ld7032 controller */
|
||||
uint8_t u8x8_cad_ld7032_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
static uint8_t in_transfer = 0;
|
||||
uint8_t *p;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
if ( in_transfer != 0 )
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
in_transfer = 1;
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
//u8x8_byte_SetDC(u8x8, 1);
|
||||
|
||||
/* the FeatherWing OLED with the 32u4 transfer of long byte */
|
||||
/* streams was not possible. This is broken down to */
|
||||
/* smaller streams, 32 seems to be the limit... */
|
||||
/* I guess this is related to the size of the Wire buffers in Arduino */
|
||||
/* Unfortunately, this can not be handled in the byte level drivers, */
|
||||
/* so this is done here. Even further, only 24 bytes will be sent, */
|
||||
/* because there will be another byte (DC) required during the transfer */
|
||||
p = arg_ptr;
|
||||
while( arg_int > 24 )
|
||||
{
|
||||
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
|
||||
arg_int-=24;
|
||||
p+=24;
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
u8x8_byte_SendByte(u8x8, 0x08); /* data write for LD7032 */
|
||||
}
|
||||
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
|
||||
break;
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||
if ( u8x8->i2c_address == 255 )
|
||||
u8x8->i2c_address = 0x060;
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
in_transfer = 0;
|
||||
break;
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
if ( in_transfer != 0 )
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* cad procedure for the UC16xx family in I2C mode */
|
||||
/* u8x8_byte_SetDC is not used */
|
||||
/* DC bit is encoded into the adr byte */
|
||||
uint8_t u8x8_cad_uc16xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
static uint8_t in_transfer = 0;
|
||||
static uint8_t is_data = 0;
|
||||
uint8_t *p;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_CAD_SEND_CMD:
|
||||
case U8X8_MSG_CAD_SEND_ARG:
|
||||
if ( in_transfer != 0 )
|
||||
{
|
||||
if ( is_data != 0 )
|
||||
{
|
||||
/* transfer mode is active, but data transfer */
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
/* clear the lowest two bits of the adr */
|
||||
u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clear the lowest two bits of the adr */
|
||||
u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
}
|
||||
u8x8_byte_SendByte(u8x8, arg_int);
|
||||
in_transfer = 1;
|
||||
break;
|
||||
case U8X8_MSG_CAD_SEND_DATA:
|
||||
if ( in_transfer != 0 )
|
||||
{
|
||||
if ( is_data == 0 )
|
||||
{
|
||||
/* transfer mode is active, but data transfer */
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
/* clear the lowest two bits of the adr */
|
||||
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clear the lowest two bits of the adr */
|
||||
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
}
|
||||
in_transfer = 1;
|
||||
|
||||
p = arg_ptr;
|
||||
while( arg_int > 24 )
|
||||
{
|
||||
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
|
||||
arg_int-=24;
|
||||
p+=24;
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
u8x8_byte_StartTransfer(u8x8);
|
||||
}
|
||||
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
|
||||
|
||||
break;
|
||||
case U8X8_MSG_CAD_INIT:
|
||||
/* apply default i2c adr if required so that the start transfer msg can use this */
|
||||
if ( u8x8->i2c_address == 255 )
|
||||
u8x8->i2c_address = 0x070;
|
||||
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
|
||||
case U8X8_MSG_CAD_START_TRANSFER:
|
||||
in_transfer = 0;
|
||||
/* actual start is delayed, because we do not whether this is data or cmd transfer */
|
||||
break;
|
||||
case U8X8_MSG_CAD_END_TRANSFER:
|
||||
if ( in_transfer != 0 )
|
||||
u8x8_byte_EndTransfer(u8x8);
|
||||
in_transfer = 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
|
||||
u8x8_d_a2printer.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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.
|
||||
|
||||
|
||||
Use DC2 bitmap command of the A2 Micro panel termal printer
|
||||
double stroke
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
#define LINE_MIN_DELAY_MS 15
|
||||
/* higher values improve quality */
|
||||
/* however if the value is too high (>=5) then form feed does not work any more */
|
||||
#define LINE_EXTRA_8PIXEL_DELAY_MS 3
|
||||
/* this must be a power of two and between 1 and 8 */
|
||||
/* best quality only with 1 */
|
||||
#define NO_OF_LINES_TO_SEND_WITHOUT_DELAY 1
|
||||
|
||||
/* calculates the delay, based on the number of black pixel */
|
||||
/* actually only "none-zero" bytes are calculated which is, of course not so accurate, but should be good enough */
|
||||
uint16_t get_delay_in_milliseconds(uint8_t cnt, uint8_t *data)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t time = LINE_MIN_DELAY_MS;
|
||||
for ( i = 0; i < cnt; i++ )
|
||||
if ( data[i] != 0 )
|
||||
time += LINE_EXTRA_8PIXEL_DELAY_MS;
|
||||
return time;
|
||||
}
|
||||
|
||||
uint8_t u8x8_d_a2printer_common(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t c, i, j;
|
||||
uint8_t *ptr;
|
||||
uint16_t delay_in_milliseconds;
|
||||
switch(msg)
|
||||
{
|
||||
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
|
||||
/*
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
// no setup required
|
||||
// u8x8_cad_SendSequence(u8x8, u8x8_d_a2printer_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
// no powersave
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 27); /* ESC */
|
||||
u8x8_cad_SendCmd(u8x8, 55 ); /* parameter command */
|
||||
/* increasing the "max printing dots" requires a good power supply, but LINE_EXTRA_8PIXEL_DELAY_MS could be reduced then */
|
||||
u8x8_cad_SendCmd(u8x8, 0); /* Max printing dots,Unit(8dots),Default:7(64 dots) 8*(x+1) ... lower values improve, probably my current supply is not sufficient */
|
||||
u8x8_cad_SendCmd(u8x8, 200); /* 3-255 Heating time,Unit(10us),Default:80(800us) */
|
||||
u8x8_cad_SendCmd(u8x8, 2); /* 0-255 Heating interval,Unit(10us),Default:2(20us) ... does not have much influence */
|
||||
|
||||
//c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
|
||||
c = u8x8->display_info->tile_width;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 18); /* DC2 */
|
||||
u8x8_cad_SendCmd(u8x8, 42 ); /* * */
|
||||
u8x8_cad_SendCmd(u8x8, 8 ); /* height */
|
||||
u8x8_cad_SendCmd(u8x8, c ); /* c, u8x8->display_info->tile_width */
|
||||
|
||||
for( j = 0; j < 8 / NO_OF_LINES_TO_SEND_WITHOUT_DELAY; j ++ )
|
||||
{
|
||||
|
||||
delay_in_milliseconds = 0;
|
||||
for( i = 0; i < NO_OF_LINES_TO_SEND_WITHOUT_DELAY; i++ )
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* c, note: SendData can not handle more than 255 bytes, send one line of data */
|
||||
delay_in_milliseconds += get_delay_in_milliseconds(c, ptr);
|
||||
ptr += c;
|
||||
}
|
||||
|
||||
while( delay_in_milliseconds > 200 )
|
||||
{
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_MILLI, 200, NULL);
|
||||
delay_in_milliseconds -= 200;
|
||||
}
|
||||
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_MILLI, delay_in_milliseconds, NULL);
|
||||
}
|
||||
|
||||
/* set parameters back to their default values */
|
||||
u8x8_cad_SendCmd(u8x8, 27); /* ESC */
|
||||
u8x8_cad_SendCmd(u8x8, 55 ); /* parameter command */
|
||||
u8x8_cad_SendCmd(u8x8, 7); /* Max printing dots,Unit(8dots),Default:7(64 dots) 8*(x+1)*/
|
||||
u8x8_cad_SendCmd(u8x8, 80); /* 3-255 Heating time,Unit(10us),Default:80(800us) */
|
||||
u8x8_cad_SendCmd(u8x8, 2); /* 0-255 Heating interval,Unit(10us),Default:2(20us)*/
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_a2printer_384x240_display_info =
|
||||
{
|
||||
/* most of the settings are not required, because this is a serial RS232 printer */
|
||||
|
||||
/* chip_enable_level = */ 1,
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 5,
|
||||
/* pre_chip_disable_wait_ns = */ 5,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140,
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* old: sck_takeover_edge, new: active high (bit 1), rising edge (bit 0) */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30,
|
||||
/* write_pulse_width_ns = */ 40,
|
||||
/* tile_width = */ 48,
|
||||
/* tile_hight = */ 30,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 384,
|
||||
/* pixel_height = */ 240
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_a2printer_384x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_a2printer_384x240_display_info);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_a2printer_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
|
||||
u8x8_d_il3820_296x128.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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.
|
||||
|
||||
il3820: 200x300x1
|
||||
|
||||
command
|
||||
0x22: assign actions
|
||||
0x20: execute actions
|
||||
|
||||
action for command 0x022 are (more or less guessed)
|
||||
bit 7: Enable Clock
|
||||
bit 6: Enable Charge Pump
|
||||
bit 5: Load Temparture Value (???)
|
||||
bit 4: Load LUT (???)
|
||||
bit 3: Initial Display (???)
|
||||
bit 2: Pattern Display --> Requires about 945ms with the LUT from below
|
||||
bit 1: Disable Charge Pump
|
||||
bit 0: Disable Clock
|
||||
|
||||
Disable Charge Pump and Clock require about 10ms
|
||||
Enable Charge Pump and Clock require about 100 to 300ms
|
||||
|
||||
Notes:
|
||||
- Introduced a refresh display message, which copies RAM to display
|
||||
- Charge pump is always enabled. Charge pump can be enabled/disabled via power save message
|
||||
- U8x8 will not really work because of the two buffers in the SSD1606, however U8g2 should be ok.
|
||||
|
||||
LUT for the 296x128 device (IL3820)
|
||||
LUT (cmd: 0x032 has 30 bytes)
|
||||
section 6.8 of the datasheet mentions 256 bits = 32 bytes for the LUT
|
||||
chapter 7 tells 30 bytes
|
||||
|
||||
according to section 6.8:
|
||||
20 bytes waveform
|
||||
10 bytes timing
|
||||
1 byte named as VSH/VSL
|
||||
1 empty byte
|
||||
according to the command table, the lut has 240 bits (=30 bytes * 8 bits)
|
||||
|
||||
|
||||
LUT / Refresh time
|
||||
total_refresh_time = (refresh_lines + dummy_lines*2)*TGate*TS_Sum/f_OSC
|
||||
|
||||
f_OSC=1MHz (according to the datasheets)
|
||||
refreh_lines = 296 (for the waveshare display, 0x045 cmd)
|
||||
dummy_lines = 22 (for the upcoming u8g2 code, 0x03a cmd)
|
||||
TGate = 62 (POR default, 0x03b cmd)
|
||||
TS_Sum: Sum of all TS entries of the second part of the LUT
|
||||
f_OSC: 1MHz according to the datasheet.
|
||||
|
||||
so we have
|
||||
|
||||
total_refresh_time = 21080*TS_Sum/1000000 = 21ms * TS_Sum
|
||||
|
||||
|
||||
This file includes two devices:
|
||||
u8x8_d_il3820_296x128 --> includes LUT which is probably from the WaveShare 2.9 Vendor
|
||||
u8x8_d_il3820_v2_296x128 --> includes LUT which was optimized for faster speed and lesser flicker
|
||||
|
||||
*/
|
||||
|
||||
/* Waveform part of the LUT (20 bytes) */
|
||||
/* bit 7/6: 1 - 1 transition */
|
||||
/* bit 5/4: 1 - 0 transition */
|
||||
/* bit 3/2: 0 - 1 transition */
|
||||
/* bit 1/0: 0 - 0 transition */
|
||||
/* 00 – VSS */
|
||||
/* 01 – VSH */
|
||||
/* 10 – VSL */
|
||||
/* 11 – NA */
|
||||
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
/*=================================================*/
|
||||
/* common code for all devices */
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_il3820_296x128_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x22, 0xc0), /* enable clock and charge pump */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(200), /* according to my measures it may take up to 150ms */
|
||||
U8X8_DLY(100), /* but it might take longer */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_il3820_296x128_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
/* disable clock and charge pump only, deep sleep is not entered, because we will loose RAM content */
|
||||
U8X8_CA(0x22, 0x02), /* only disable charge pump, HW reset seems to be required if the clock is disabled */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(20),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_il3820_296x128_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_il3820_296x128_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_il3820_296x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 120,
|
||||
/* pre_chip_disable_wait_ns = */ 60,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100,
|
||||
/* sda_setup_time_ns = */ 50, /* IL3820 */
|
||||
/* sck_pulse_width_ns = */ 125, /* IL3820: 125ns, clock cycle = 250ns */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150,
|
||||
/* tile_width = */ 37, /* 37*8 = 296 */
|
||||
/* tile_hight = */ 16, /* 16*8 = 128 */
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 296,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
|
||||
static uint8_t *u8x8_convert_tile_for_il3820(uint8_t *t)
|
||||
{
|
||||
uint8_t i;
|
||||
static uint8_t buf[8];
|
||||
uint8_t *pbuf = buf;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
*pbuf++ = ~(*t++);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void u8x8_d_il3820_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
|
||||
static void u8x8_d_il3820_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint16_t x;
|
||||
uint8_t c, page;
|
||||
uint8_t *ptr;
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
page = u8x8->display_info->tile_height;
|
||||
page --;
|
||||
page -= (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
//u8x8_cad_SendCmd(u8x8, 0x011 ); /* cursor increment mode */
|
||||
//u8x8_cad_SendArg(u8x8, 7);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x04f ); /* set cursor column */
|
||||
u8x8_cad_SendArg(u8x8, x&255);
|
||||
u8x8_cad_SendArg(u8x8, x>>8);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x04e ); /* set cursor row */
|
||||
u8x8_cad_SendArg(u8x8, page);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x024 );
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 8, u8x8_convert_tile_for_il3820(ptr));
|
||||
ptr += 8;
|
||||
x += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_il3820_exec_1000dly_seq[] = {
|
||||
// assumes, that the start transfer has happend
|
||||
U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static void u8x8_d_il3820_first_init(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8_ClearDisplay(u8x8);
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x032); // program update sequence
|
||||
u8x8_cad_SendMultipleArg(u8x8, 8, 0x055); // all black
|
||||
u8x8_cad_SendMultipleArg(u8x8, 12, 0x0aa); // all white
|
||||
u8x8_cad_SendMultipleArg(u8x8, 10, 0x022); // 830ms
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_exec_1000dly_seq);
|
||||
|
||||
}
|
||||
|
||||
#ifdef OBSOLETE
|
||||
static void u8x8_d_il3820_second_init(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8_ClearDisplay(u8x8);
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x032); // program update sequence
|
||||
u8x8_cad_SendMultipleArg(u8x8, 20, 0x000); // do nothing
|
||||
u8x8_cad_SendMultipleArg(u8x8, 10, 0x011); // 414ms dly
|
||||
/* reuse sequence from above, ok some time is wasted here, */
|
||||
/* delay could be lesser */
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_exec_1000dly_seq);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*=================================================*/
|
||||
/* first version, LUT from WaveShare */
|
||||
|
||||
|
||||
/* http://www.waveshare.com/wiki/File:2.9inch_e-Paper_Module_code.7z */
|
||||
static const uint8_t u8x8_d_il3820_296x128_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: Disable */
|
||||
U8X8_C(0x01),
|
||||
U8X8_A(295 % 256), U8X8_A(295/256), U8X8_A(0),
|
||||
|
||||
|
||||
U8X8_CA(0x03, 0x00), /* Gate Driving voltage: 15V (lowest value)*/
|
||||
U8X8_CA(0x04, 0x0a), /* Source Driving voltage: 15V (mid value and POR)*/
|
||||
|
||||
//U8X8_CA(0x22, 0xc0), /* display update seq. option: enable clk, enable CP, .... todo: this is never activated */
|
||||
|
||||
//U8X8_CA(0x0b, 7), /* Set Delay of gate and source non overlap period, POR = 7 */
|
||||
U8X8_CA(0x2c, 0xa8), /* write vcom value*/
|
||||
U8X8_CA(0x3a, 0x16), /* dummy lines POR=22 (0x016) */
|
||||
U8X8_CA(0x3b, 0x08), /* gate time POR=0x08*/
|
||||
U8X8_CA(0x3c, 0x33), /* select boarder waveform */
|
||||
//U8X8_CA(0x22, 0xc4), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
|
||||
|
||||
|
||||
U8X8_CA(0x11, 0x07), /* Define data entry mode, x&y inc, x first*/
|
||||
|
||||
U8X8_CAA(0x44, 0, 29), /* RAM x start & end, 32*4=128 */
|
||||
U8X8_CAAAA(0x45, 0, 0, 295&255, 295>>8), /* RAM y start & end, 0..295 */
|
||||
|
||||
//U8X8_CA(0x4e, 0), /* set x pos, 0..29? */
|
||||
//U8X8_CAA(0x4f, 0, 0), /* set y pos, 0...320??? */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_il3820_to_display_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
/*
|
||||
0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
measured 1582 ms
|
||||
*/
|
||||
U8X8_C(0x32), /* write LUT register*/
|
||||
/* original values */
|
||||
U8X8_A(0x50),
|
||||
U8X8_A(0xaa),
|
||||
U8X8_A(0x55),
|
||||
U8X8_A(0xaa),
|
||||
U8X8_A(0x11),
|
||||
|
||||
U8X8_A(0x11),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
|
||||
/* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */
|
||||
U8X8_A(0xff),
|
||||
U8X8_A(0xff),
|
||||
U8X8_A(0x3f),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
|
||||
U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display, assumes clk and charge pump are enabled */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
|
||||
U8X8_DLY(250), /* delay for 1620ms. The current sequence takes 1582ms */
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(120),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_il3820_296x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_il3820_296x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_init_seq);
|
||||
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave0_seq);
|
||||
u8x8_d_il3820_first_init(u8x8);
|
||||
|
||||
/* usually the DISPLAY_INIT message leaves the display in power save state */
|
||||
/* however this is not done for e-paper devices, see: */
|
||||
/* https://github.com/olikraus/u8g2/wiki/internal#powersave-mode */
|
||||
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_d_il3820_draw_tile(u8x8, arg_int, arg_ptr);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_REFRESH:
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_to_display_seq);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=================================================*/
|
||||
/* second version for the IL3820 display */
|
||||
|
||||
|
||||
/* http://www.waveshare.com/wiki/File:2.9inch_e-Paper_Module_code.7z */
|
||||
static const uint8_t u8x8_d_il3820_v2_296x128_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
// U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: POR: Normal mode */
|
||||
U8X8_C(0x01),
|
||||
U8X8_A(295 % 256), U8X8_A(295/256), U8X8_A(0),
|
||||
|
||||
/* the driving voltagesmust not be that high, in order to aviod level change after */
|
||||
/* some seconds (which happens with 0xea */
|
||||
U8X8_CA(0x03, 0x75), /* Gate Driving voltage: +/-15V =0x00 POR (+22/-20V) = 0x0ea*/
|
||||
U8X8_CA(0x04, 0x0a), /* Source Driving voltage: (POR=0x0a=15V), max=0x0e*/
|
||||
|
||||
U8X8_CA(0x0b, 7), /* Set Delay of gate and source non overlap period, POR = 7 */
|
||||
U8X8_CA(0x2c, 0xa8), /* write vcom value*/
|
||||
U8X8_CA(0x3a, 0x16), /* dummy lines POR=22 (0x016) */
|
||||
U8X8_CA(0x3b, 0x08), /* gate time POR=0x08*/
|
||||
U8X8_CA(0x3c, 0x33), /* select boarder waveform */
|
||||
|
||||
U8X8_CA(0x11, 0x07), /* Define data entry mode, x&y inc, x first*/
|
||||
U8X8_CAA(0x44, 0, 29), /* RAM x start & end, 32*4=128 */
|
||||
U8X8_CAAAA(0x45, 0, 0, 295&255, 295>>8), /* RAM y start & end, 0..295 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_il3820_v2_to_display_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
/*
|
||||
0xaa, 0x09, 0x09, 0x19, 0x19,
|
||||
0x11, 0x11, 0x11, 0x11, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x75, 0x77, 0x77, 0x77, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00
|
||||
measured 1240 ms
|
||||
*/
|
||||
U8X8_C(0x32), /* write LUT register*/
|
||||
/* https://github.com/olikraus/u8g2/issues/347 */
|
||||
U8X8_A(0xaa),
|
||||
U8X8_A(0x09),
|
||||
U8X8_A(0x09),
|
||||
U8X8_A(0x19),
|
||||
U8X8_A(0x19),
|
||||
|
||||
U8X8_A(0x11),
|
||||
U8X8_A(0x11),
|
||||
U8X8_A(0x11),
|
||||
U8X8_A(0x11),
|
||||
U8X8_A(0x00),
|
||||
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
|
||||
/* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */
|
||||
U8X8_A(0x75),
|
||||
U8X8_A(0x77),
|
||||
U8X8_A(0x77),
|
||||
U8X8_A(0x77),
|
||||
U8X8_A(0x07),
|
||||
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
|
||||
U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
|
||||
U8X8_DLY(250), /* delay for 1400ms. The current sequence takes 1240ms, it was reported, that longer delays are better */
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(150), /* extended, #318 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_il3820_v2_296x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_il3820_296x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_v2_296x128_init_seq);
|
||||
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave0_seq);
|
||||
u8x8_d_il3820_first_init(u8x8);
|
||||
/* u8x8_d_il3820_second_init(u8x8); */ /* not required, u8g2.begin() will also clear the display once more */
|
||||
|
||||
/* usually the DISPLAY_INIT message leaves the display in power save state */
|
||||
/* however this is not done for e-paper devices, see: */
|
||||
/* https://github.com/olikraus/u8g2/wiki/internal#powersave-mode */
|
||||
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_d_il3820_draw_tile(u8x8, arg_int, arg_ptr);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_REFRESH:
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_v2_to_display_seq);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ist3020.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ist3020_erc19264_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a4), /* all pixel off, issue 142 */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ist3020_erc19264_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ist3020_erc19264_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ist3020_erc19264_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ist3020_erc19264_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* IST3020 datasheet, page 56 */
|
||||
/* pre_chip_disable_wait_ns = */ 150, /* IST3020 datasheet, page 56 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 100, /* IST3020 datasheet, page 56 */
|
||||
/* sck_pulse_width_ns = */ 100, /* IST3020 datasheet, page 56 */
|
||||
/* sck_clock_hz = */ 4000000UL, /* */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* IST3020 datasheet, page 54 */
|
||||
/* write_pulse_width_ns = */ 60, /* IST3020 datasheet, page 54 */
|
||||
/* tile_width = */ 24, /* width of 24*8=192 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 64,
|
||||
/* pixel_width = */ 192,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ist3020_erc19264_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ab), /* build in osc on, used in ER code, but not mentioned in data sheet */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
U8X8_C(0x0c8), /* common output mode */
|
||||
// Flipmode
|
||||
//U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a3), /* FIX: LCD bias 1/7, old value was 1/9 (0x0a2) */
|
||||
|
||||
U8X8_C(0x028|4), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
U8X8_C(0x028|6), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
U8X8_C(0x028|7), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_C(0x020), /* v0 voltage resistor ratio */
|
||||
U8X8_CA(0x081, 0x019), /* set contrast, contrast value (from ER code: 45) */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ist3020_erc19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ist3020_erc19264_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ks0108.c
|
||||
|
||||
The classic 5V LCD
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ks0108_init_seq[] = {
|
||||
U8X8_C(0x0c0), /* satart at the top */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ks0108_powersave0_seq[] = {
|
||||
U8X8_C(0x03f), /* display on */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ks0108_powersave1_seq[] = {
|
||||
U8X8_C(0x03e), /* display off */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
struct u8x8_ks0108_vars
|
||||
{
|
||||
uint8_t *ptr;
|
||||
uint8_t x;
|
||||
uint8_t c;
|
||||
uint8_t arg_int;
|
||||
};
|
||||
|
||||
static void u8x8_ks0108_out(u8x8_t *u8x8, struct u8x8_ks0108_vars *v, void *arg_ptr)
|
||||
{
|
||||
uint8_t cnt;
|
||||
u8x8_cad_SendCmd(u8x8, 0x040 | ((v->x << 3) & 63) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b8 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
while( v->arg_int > 0 )
|
||||
{
|
||||
/* calculate tiles to next boundary (end or chip limit) */
|
||||
cnt = v->x;
|
||||
cnt += 8;
|
||||
cnt &= 0x0f8;
|
||||
cnt -= v->x;
|
||||
|
||||
if ( cnt > v->c )
|
||||
cnt = v->c;
|
||||
|
||||
/* of cours we still could use cnt=1 here... */
|
||||
/* but setting cnt to 1 is not very efficient */
|
||||
//cnt = 1;
|
||||
|
||||
v->x +=cnt;
|
||||
v->c-=cnt;
|
||||
cnt<<=3;
|
||||
u8x8_cad_SendData(u8x8, cnt, v->ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
v->ptr += cnt;
|
||||
|
||||
if ( v->c == 0 )
|
||||
{
|
||||
v->ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
v->c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
v->arg_int--;
|
||||
}
|
||||
if ( ((v->x) & 7) == 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ks0108_128x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0, /* KS0108: Not used */
|
||||
/* chip_disable_level = */ 1, /* KS0108: Not used */
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 100,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6, /* could be faster for the KS0108 */
|
||||
/* sda_setup_time_ns = */ 12,
|
||||
/* sck_pulse_width_ns = */ 75, /* KS0108: Not used */
|
||||
/* sck_clock_hz = */ 4000000UL, /* KS0108: Not used */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4, /* KS0108: Not used */
|
||||
/* data_setup_time_ns = */ 200,
|
||||
/* write_pulse_width_ns = */ 200, /* KS0108: actially 450 ns */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ks0108_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
struct u8x8_ks0108_vars v;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ks0108_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 2, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 2, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 2, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
}
|
||||
break;
|
||||
// The KS0108 can not mirror the cols and rows, use U8g2 for rotation
|
||||
// case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
// break;
|
||||
// The KS0108 has no internal contrast command
|
||||
// case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
// break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
|
||||
v.ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
v.x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
v.c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
v.arg_int = arg_int;
|
||||
|
||||
|
||||
if ( v.x < 8 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
|
||||
u8x8_ks0108_out(u8x8, &v, arg_ptr);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
}
|
||||
if ( v.x < 16 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 2, NULL);
|
||||
u8x8_ks0108_out(u8x8, &v, arg_ptr);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
}
|
||||
//if ( v.x < 24 )
|
||||
//{
|
||||
//u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 4, NULL);
|
||||
//u8x8_ks0108_out(u8x8, &v, arg_ptr);
|
||||
//u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
//}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* east rising (buydisplay.com) ERM19264 */
|
||||
/* left: 011, middle: 101, right: 110, no chip select: 111 */
|
||||
uint8_t u8x8_d_ks0108_erm19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
struct u8x8_ks0108_vars v;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ks0108_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 3, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 5, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 6, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 3, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 5, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 6, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 3, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 5, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 6, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
|
||||
}
|
||||
break;
|
||||
// The KS0108 can not mirror the cols and rows, use U8g2 for rotation
|
||||
// case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
// break;
|
||||
// The KS0108 has no internal contrast command
|
||||
// case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
// break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
|
||||
v.ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
v.x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
v.c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
v.arg_int = arg_int;
|
||||
|
||||
|
||||
if ( v.x < 8 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 3, NULL);
|
||||
u8x8_ks0108_out(u8x8, &v, arg_ptr);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
}
|
||||
if ( v.x < 16 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 5, NULL);
|
||||
u8x8_ks0108_out(u8x8, &v, arg_ptr);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
}
|
||||
if ( v.x < 24 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 6, NULL);
|
||||
u8x8_ks0108_out(u8x8, &v, arg_ptr);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
|
||||
u8x8_d_lc7981.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* no powersave mode for the LC7981 */
|
||||
static const uint8_t u8x8_d_lc7981_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_lc7981_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
/* no hardware flip for the LC7981 */
|
||||
static const uint8_t u8x8_d_lc7981_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_lc7981_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/* http://graphics.stanford.edu/~seander/bithacks.html */
|
||||
static uint8_t reverse_byte(uint8_t v)
|
||||
{
|
||||
// if ( v != 0 && v != 255 ) does not help much
|
||||
{
|
||||
// swap odd and even bits
|
||||
v = ((v >> 1) & 0x055) | ((v & 0x055) << 1);
|
||||
// swap consecutive pairs
|
||||
v = ((v >> 2) & 0x033) | ((v & 0x033) << 2);
|
||||
// swap nibbles ...
|
||||
v = ((v >> 4) & 0x00F) | ((v & 0x00F) << 4);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static uint8_t u8x8_d_lc7981_common(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t c, i, j;
|
||||
uint16_t y;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
y*=8;
|
||||
y*= u8x8->display_info->tile_width;
|
||||
/* x = ((u8x8_tile_t *)arg_ptr)->x_pos; x is ignored... no u8x8 support */
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
/*
|
||||
Tile structure is reused here for the t6963, however u8x8 is not supported
|
||||
tile_ptr points to data which has cnt*8 bytes (same as SSD1306 tiles)
|
||||
Buffer is expected to have 8 lines of code fitting to the t6963 internal memory
|
||||
"cnt" includes the number of horizontal bytes. width is equal to cnt*8
|
||||
|
||||
x is assumed to be zero
|
||||
|
||||
TODO: Consider arg_int, however arg_int is not used by u8g2
|
||||
*/
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
u8x8_cad_SendCmd(u8x8, 0x0a ); /* display ram (cursor) address low byte */
|
||||
u8x8_cad_SendArg(u8x8, y&255);
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b ); /* display ram (cursor) address high byte */
|
||||
u8x8_cad_SendArg(u8x8, y>>8);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x0c ); /* write start */
|
||||
/*
|
||||
The LC7981 has the MSB at the right position, which is exactly the opposite to the T6963.
|
||||
Instead of writing a third hvline procedure for this device, we just revert the bytes before
|
||||
transmit. This is slow because:
|
||||
- the bit reverse itself
|
||||
- the single byte transfer
|
||||
The one byte is transmitted via SendArg, which is ok, because CAD = 100
|
||||
*/
|
||||
for( j = 0; j < c; j++ )
|
||||
u8x8_cad_SendArg(u8x8, reverse_byte(*ptr++));
|
||||
|
||||
//u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes, send one line of data */
|
||||
//ptr += u8x8->display_info->tile_width;
|
||||
|
||||
y += u8x8->display_info->tile_width;
|
||||
}
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
/* handled in the calling procedure
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
|
||||
break;
|
||||
*/
|
||||
/* power save is not there...
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_powersave1_seq);
|
||||
break;
|
||||
*/
|
||||
/* hardware flip not is not available
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
/* no contrast setting :-(
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int );
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
*/
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* LC7981 160x80 LCD*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_lc7981_160x80_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0, /* LC7981 has a low active CS*/
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* from here... */
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 10,
|
||||
/* sda_setup_time_ns = */ 30,
|
||||
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* ... to here, values are ignored, because this is a parallel interface only */
|
||||
|
||||
/* data_setup_time_ns = */ 220,
|
||||
/* write_pulse_width_ns = */ 20,
|
||||
/* tile_width = */ 20, /* width of 20*8=160 pixel */
|
||||
/* tile_hight = */ 10,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 160,
|
||||
/* pixel_height = */ 80
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_lc7981_160x80_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_CA(0x00, 0x32), /* display on (bit 5), master mode on (bit 4), graphics mode on (bit 1) */
|
||||
U8X8_CA(0x01, 0x07), /* character/bits per pixel pitch */
|
||||
U8X8_CA(0x02, 160/8-1), /* number of chars/byte width of the screen */
|
||||
U8X8_CA(0x03, 0x50), /* time division: 50 (1/80 duty cycle) */
|
||||
U8X8_CA(0x08, 0x00), /* display start low */
|
||||
U8X8_CA(0x09, 0x00), /* display start high */
|
||||
|
||||
U8X8_DLY(10),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_lc7981_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_lc7981_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_160x80_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_160x80_init_seq);
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* LC7981 160x160 LCD*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_lc7981_160x160_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0, /* LC7981 has a low active CS*/
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* from here... */
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 10,
|
||||
/* sda_setup_time_ns = */ 30,
|
||||
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* ... to here, values are ignored, because this is a parallel interface only */
|
||||
|
||||
/* data_setup_time_ns = */ 220,
|
||||
/* write_pulse_width_ns = */ 20,
|
||||
/* tile_width = */ 20, /* width of 20*8=160 pixel */
|
||||
/* tile_hight = */ 20,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 160,
|
||||
/* pixel_height = */ 160
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_lc7981_160x160_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_CA(0x00, 0x32), /* display on (bit 5), master mode on (bit 4), graphics mode on (bit 1) */
|
||||
U8X8_CA(0x01, 0x07), /* character/bits per pixel pitch */
|
||||
U8X8_CA(0x02, 160/8-1), /* number of chars/byte width of the screen */
|
||||
U8X8_CA(0x03, 159), /* time division */
|
||||
U8X8_CA(0x08, 0x00), /* display start low */
|
||||
U8X8_CA(0x09, 0x00), /* display start high */
|
||||
|
||||
U8X8_DLY(10),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_lc7981_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_lc7981_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_160x160_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_160x160_init_seq);
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* LC7981 240x128 LCD*/
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
static const u8x8_display_info_t u8x8_lc7981_240x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0, /* LC7981 has a low active CS*/
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* from here... */
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 10,
|
||||
/* sda_setup_time_ns = */ 30,
|
||||
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* ... to here, values are ignored, because this is a parallel interface only */
|
||||
|
||||
/* data_setup_time_ns = */ 220,
|
||||
/* write_pulse_width_ns = */ 20,
|
||||
/* tile_width = */ 30, /* width of 30*8=240 pixel */
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_lc7981_240x128_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_CA(0x00, 0x32), /* display on (bit 5), master mode on (bit 4), graphics mode on (bit 1) */
|
||||
U8X8_CA(0x01, 0x07), /* character/bits per pixel pitch */
|
||||
U8X8_CA(0x02, 240/8-1), /* number of chars/byte width of the screen */
|
||||
U8X8_CA(0x03, 0x7f), /* time division */
|
||||
U8X8_CA(0x08, 0x00), /* display start low */
|
||||
U8X8_CA(0x09, 0x00), /* display start high */
|
||||
|
||||
U8X8_DLY(10),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_lc7981_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_lc7981_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_240x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_240x128_init_seq);
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ld7032_60x32.c
|
||||
Note: Flip Mode is NOT supported
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
/* testboard U8GLIB_LD7032_60x32 u8g(11, 12, 9, 10, 8); // SPI Com: SCK = 11, MOSI = 12, CS = 9, A0 = 10, RST = 8 (SW SPI Nano Board) */
|
||||
/* http://www.seeedstudio.com/document/pdf/0.5OLED%20SPEC.pdf */
|
||||
static const uint8_t u8x8_d_ld7032_60x32_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
//U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
|
||||
U8X8_CA(0x014, 0x000), /* Stand-by OFF */
|
||||
U8X8_CA(0x01a, 0x004), /* Dot Matrix Frame Rate, special value for this OLED from manual*/
|
||||
U8X8_CA(0x01d, 0x000), /* Graphics Memory Writing Direction: reset default (right down, horizontal) */
|
||||
U8X8_CA(0x009, 0x000), /* Display Direction: reset default (x,y: min --> max) */
|
||||
U8X8_CAA(0x030, 0x000, 0x03b), /* Display Size X, Column Start - End*/
|
||||
U8X8_CAA(0x032, 0x000, 0x01f), /* Display Size Y, Row Start - End*/
|
||||
U8X8_CA(0x010, 0x000), /* Peak Pulse Width Set: 0 SCLK */
|
||||
U8X8_CA(0x016, 0x000), /* Peak Pulse Delay Set: 0 SCLK */
|
||||
U8X8_CA(0x012, 0x040), /* Dot Matrix Current Level Set: 0x050 * 1 uA = 80 uA */
|
||||
U8X8_CA(0x018, 0x003), /* Pre-Charge Pulse Width: 3 SCLK */
|
||||
U8X8_CA(0x044, 0x002), /* Pre-Charge Mode: Every Time */
|
||||
U8X8_CA(0x048, 0x003), /* Row overlap timing: Pre-Charge + Peak Delay + Peak boot Timing */
|
||||
U8X8_CA(0x03f, 0x011), /* VCC_R_SEL: ??? */
|
||||
U8X8_CA(0x03d, 0x000), /* VSS selection: 2.8V */
|
||||
//U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ld7032_60x32_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ld7032_60x32_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x002, 0x000), /* Dot Matrix Display ON */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ld7032_60x32_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x009, 0x000), /* Display Direction: reset default (x,y: min --> max) */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ld7032_60x32_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
//U8X8_CA(0x009, 0x002), /* Display Direction: reset default (x,y: min --> max) */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ld7032_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_60x32_display_info);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x012 );
|
||||
if ( arg_int > 0x07f ) /* default is 0x040, limit to 0x07f to be on the safe side (hopefully) */
|
||||
arg_int= 0x07f;
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* values from 0x00 to 0x0ff are allowed, bit will all values be safe??? */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x += u8x8->x_offset/8;
|
||||
u8x8_cad_SendCmd(u8x8, 0x034 );
|
||||
u8x8_cad_SendArg(u8x8, x );
|
||||
u8x8_cad_SendCmd(u8x8, 0x035 );
|
||||
u8x8_cad_SendArg(u8x8, 0x007 );
|
||||
u8x8_cad_SendCmd(u8x8, 0x036 );
|
||||
u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos)*8 );
|
||||
u8x8_cad_SendCmd(u8x8, 0x037 );
|
||||
u8x8_cad_SendArg(u8x8, 0x01f );
|
||||
u8x8_cad_SendCmd(u8x8, 0x008 );
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ld7032_60x32_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 15,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100,
|
||||
/* sda_setup_time_ns = */ 30, /* 20ns, but cycle time is 60ns, so use 60/2 */
|
||||
/* sck_pulse_width_ns = */ 30, /* 20ns, but cycle time is 60ns, so use 60/2 */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 20,
|
||||
/* write_pulse_width_ns = */ 40,
|
||||
/* tile_width = */ 8,
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 60,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ld7032_60x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_60x32_display_info);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ld7032_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ls013b7dh03.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, olikraus@gmail.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
The LS013B7DH02 is a simple display and controller
|
||||
--> no support for contrast adjustment, flip and power down.
|
||||
*/
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
#define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7))
|
||||
|
||||
#define LS013B7DH03_CMD_UPDATE (0x01)
|
||||
#define LS013B7DH03_CMD_ALL_CLEAR (0x04)
|
||||
#define LS013B7DH03_VAL_TRAILER (0x00)
|
||||
|
||||
static const u8x8_display_info_t u8x8_ls013b7dh03_128x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1,
|
||||
/* chip_disable_level = */ 0,
|
||||
/* post_chip_enable_wait_ns = */ 50,
|
||||
/* pre_chip_disable_wait_ns = */ 50,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 227, /* 227 nsec according to the datasheet */
|
||||
/* sck_pulse_width_ns = */ 255, /* 450 nsec according to the datasheet */
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 2, /* active low, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 100,
|
||||
/* write_pulse_width_ns = */ 100,
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ls013b7dh03_128x128(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t y, c, i;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ls013b7dh03_128x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
|
||||
/* clear screen */
|
||||
u8x8_cad_SendCmd(u8x8, SWAP8(LS013B7DH03_CMD_ALL_CLEAR) );
|
||||
u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER);
|
||||
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
/* not available for the ls013b7dh03 */
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
/* each tile is 8 lines, with the data starting at the left edge */
|
||||
y = ((((u8x8_tile_t *)arg_ptr)->y_pos) * 8) + 1;
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
|
||||
/* send data mode byte */
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, SWAP8(LS013B7DH03_CMD_UPDATE) );
|
||||
|
||||
/* send 8 lines of 16 bytes (=128 pixels) */
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
u8x8_cad_SendCmd(u8x8, SWAP8(y + i) );
|
||||
u8x8_cad_SendData(u8x8, c, ptr);
|
||||
u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER);
|
||||
|
||||
ptr += c;
|
||||
}
|
||||
|
||||
/* finish with a trailing byte */
|
||||
u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER);
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
|
||||
u8x8_d_max7219.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_max7219_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(15, 0), /* test mode off */
|
||||
U8X8_CA(15, 0), /* test mode off */
|
||||
U8X8_CA(15, 0), /* test mode off */
|
||||
U8X8_CA(15, 0), /* test mode off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(12, 0), /* */
|
||||
U8X8_CA(12, 0), /* */
|
||||
U8X8_CA(12, 0), /* */
|
||||
U8X8_CA(12, 0), /* */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(9, 0), /* decode mode: graphics */
|
||||
U8X8_CA(9, 0), /* decode mode: graphics */
|
||||
U8X8_CA(9, 0), /* decode mode: graphics */
|
||||
U8X8_CA(9, 0), /* decode mode: graphics */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(10, 10), /* medium high intensity */
|
||||
U8X8_CA(10, 10), /* medium high intensity */
|
||||
U8X8_CA(10, 10), /* medium high intensity */
|
||||
U8X8_CA(10, 10), /* medium high intensity */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
|
||||
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
|
||||
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
|
||||
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
|
||||
|
||||
//U8X8_CA(12, 0), /* shutdown */
|
||||
|
||||
//U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_max7219_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(12, 1), /* display on */
|
||||
U8X8_CA(12, 1), /* display on */
|
||||
U8X8_CA(12, 1), /* display on */
|
||||
U8X8_CA(12, 1), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_max7219_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(12, 0), /* shutdown */
|
||||
U8X8_CA(12, 0), /* shutdown */
|
||||
U8X8_CA(12, 0), /* shutdown */
|
||||
U8X8_CA(12, 0), /* shutdown */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t u8x8_d_max7219_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t c, j, i;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_powersave1_seq);
|
||||
break;
|
||||
/* not supported by MAX7219
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
break;
|
||||
*/
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 10 ); /* brightness */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int>>4) ); /* 0..15 for contrast */
|
||||
u8x8_cad_SendCmd(u8x8, 10 ); /* brightness */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int>>4) ); /* 0..15 for contrast */
|
||||
u8x8_cad_SendCmd(u8x8, 10 ); /* brightness */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int>>4) ); /* 0..15 for contrast */
|
||||
u8x8_cad_SendCmd(u8x8, 10 ); /* brightness */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int>>4) ); /* 0..15 for contrast */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
/* transfer always has to start at x pos 0 (u8x8 is not supported) */
|
||||
/* also y pos has to be 0 */
|
||||
/* arg_int is ignored */
|
||||
//x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
for( j = 0; j < c; j++ )
|
||||
{
|
||||
u8x8_cad_SendCmd(u8x8, i+1);
|
||||
u8x8_cad_SendArg(u8x8, *ptr );
|
||||
ptr++;
|
||||
}
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_max7219_32x8_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 100,
|
||||
/* pre_chip_disable_wait_ns = */ 100,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100,
|
||||
/* sda_setup_time_ns = */ 100,
|
||||
/* sck_pulse_width_ns = */ 100,
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150,
|
||||
/* tile_width = */ 4,
|
||||
/* tile_hight = */ 1,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 32,
|
||||
/* pixel_height = */ 16
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_max7219_32x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_max7219_32x8_display_info);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_max7219_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
|
||||
u8x8_d_pcd8544_84x48.c (so called "Nokia 5110" displays)
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_pcd8544_84x48_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x021), /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */
|
||||
U8X8_C(0x006), /* temp. control: b10 = 2 */
|
||||
U8X8_C(0x013), /* bias system 1:48 */
|
||||
U8X8_C(0x0c0), /* medium Vop */
|
||||
|
||||
U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
U8X8_C(0x008), /* blank */
|
||||
U8X8_C(0x024), /* power down (PD=1), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_pcd8544_84x48_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
U8X8_C(0x00c), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_pcd8544_84x48_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
U8X8_C(0x008), /* blank */
|
||||
U8X8_C(0x024), /* power down (PD=1), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_pcd8544_84x48_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 5,
|
||||
/* pre_chip_disable_wait_ns = */ 5,
|
||||
/* reset_pulse_width_ms = */ 2,
|
||||
/* post_reset_wait_ms = */ 2,
|
||||
/* sda_setup_time_ns = */ 12,
|
||||
/* sck_pulse_width_ns = */ 75, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30,
|
||||
/* write_pulse_width_ns = */ 40,
|
||||
/* tile_width = */ 11, /* width of 11*8=88 pixel */
|
||||
/* tile_hight = */ 6,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 84,
|
||||
/* pixel_height = */ 48
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_pcd8544_84x48(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcd8544_84x48_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_powersave1_seq);
|
||||
break;
|
||||
// case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
// break; NOT SUPPORTED
|
||||
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x021 ); /* command mode, extended function set */
|
||||
u8x8_cad_SendCmd(u8x8, 0x080 | (arg_int >> 1) );
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x020 ); /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
u8x8_cad_SendCmd(u8x8, 0x080 | (x) ); /* set X address */
|
||||
u8x8_cad_SendCmd(u8x8, 0x040 | (((u8x8_tile_t *)arg_ptr)->y_pos) ); /* set Y address */
|
||||
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
do
|
||||
{
|
||||
if ( c + x > 84u )
|
||||
{
|
||||
if ( x >= 84u )
|
||||
break;
|
||||
c = 84u;
|
||||
c -= x;
|
||||
}
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
x += c;
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
|
||||
u8x8_d_pcf8812.c
|
||||
|
||||
pcf8812: 65x102
|
||||
pcf8814: 65x96
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_pcf8812_96x65_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
U8X8_C(0x008), /* blank display */
|
||||
|
||||
U8X8_C(0x021), /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */
|
||||
U8X8_C(0x006), /* temp. control: b10 = 2 */
|
||||
U8X8_C(0x013), /* bias system, 0x010..0x07 1:48 */
|
||||
U8X8_C(0x09f), /* contrast setting, 0..127 */
|
||||
//U8X8_CA(0x020 | 2, 0x080 | 0), /* contrast setting, pcf8814 */
|
||||
|
||||
U8X8_C(0x024), /* deactivate chip (PD=1), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_pcf8812_96x65_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x020), /* power on */
|
||||
U8X8_C(0x00c), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_pcf8812_96x65_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x020), /* power on */
|
||||
U8X8_C(0x008), /* blank display */
|
||||
U8X8_C(0x024), /* power down */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t u8x8_d_pcf8812_96x65_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave1_seq);
|
||||
break;
|
||||
/*
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x021 ); /* command mode, extended function set */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int>>1)|0x80 ); /* 0..127 for contrast */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x020 ); /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
|
||||
u8x8_cad_SendCmd(u8x8, 0x080 | x);
|
||||
u8x8_cad_SendCmd(u8x8, 0x040 | ((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
/*
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 8, ptr);
|
||||
ptr += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
*/
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_pcf8812_96x65_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 100,
|
||||
/* pre_chip_disable_wait_ns = */ 100,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100,
|
||||
/* sda_setup_time_ns = */ 100,
|
||||
/* sck_pulse_width_ns = */ 100,
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150,
|
||||
/* tile_width = */ 12,
|
||||
/* tile_hight = */ 9,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 96,
|
||||
/* pixel_height = */ 65
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_pcf8812_96x65(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_pcf8812_96x65_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
|
||||
u8x8_d_sbn1661.c
|
||||
|
||||
SED1520 / SBN1661 122x32 5V LCD
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_sbn1661_init_seq[] = {
|
||||
U8X8_C(0x0c0), /* display start at line 0 */
|
||||
U8X8_C(0x0a0), /* a0: ADC forward, a1: ADC reverse */
|
||||
U8X8_C(0x0a4), /* a4: normal driving, a5: power save */
|
||||
U8X8_C(0x0a9), /* a8: 1/16, a9: 1/32 duty */
|
||||
|
||||
//U8X8_C(0x0af), /* display on */
|
||||
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_sbn1661_powersave0_seq[] = {
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_sbn1661_powersave1_seq[] = {
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
struct u8x8_sbn1661_vars
|
||||
{
|
||||
uint8_t *ptr;
|
||||
uint8_t x;
|
||||
uint8_t c;
|
||||
uint8_t arg_int;
|
||||
};
|
||||
|
||||
static void u8x8_sbn1661_out(u8x8_t *u8x8, struct u8x8_sbn1661_vars *v, void *arg_ptr)
|
||||
{
|
||||
uint8_t cnt;
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((v->x << 3) & 63) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b8 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
while( v->arg_int > 0 )
|
||||
{
|
||||
/* calculate tiles to next boundary (end or chip limit) */
|
||||
cnt = v->x;
|
||||
cnt += 8;
|
||||
cnt &= 0x0f8;
|
||||
cnt -= v->x;
|
||||
|
||||
if ( cnt > v->c )
|
||||
cnt = v->c;
|
||||
|
||||
/* of course we still could use cnt=1 here... */
|
||||
/* but setting cnt to 1 is not very efficient */
|
||||
//cnt = 1;
|
||||
|
||||
v->x +=cnt;
|
||||
v->c-=cnt;
|
||||
cnt<<=3;
|
||||
u8x8_cad_SendData(u8x8, cnt, v->ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
v->ptr += cnt;
|
||||
|
||||
if ( v->c == 0 )
|
||||
{
|
||||
v->ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
v->c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
v->arg_int--;
|
||||
}
|
||||
if ( ((v->x) & 7) == 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_sbn1661_122x32_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0, /* sbn1661: Not used */
|
||||
/* chip_disable_level = */ 1, /* sbn1661: Not used */
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 100,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6, /* */
|
||||
/* sda_setup_time_ns = */ 12,
|
||||
/* sck_pulse_width_ns = */ 75, /* sbn1661: Not used */
|
||||
/* sck_clock_hz = */ 4000000UL, /* sbn1661: Not used */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4, /* sbn1661: Not used */
|
||||
/* data_setup_time_ns = */ 200,
|
||||
/* write_pulse_width_ns = */ 200, /* */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 122,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_sbn1661_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
//uint8_t x;
|
||||
//uint8_t c;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sbn1661_122x32_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_init_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_init_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 1, NULL);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_powersave0_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_powersave0_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 1, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_powersave1_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_powersave1_seq);
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 1, NULL);
|
||||
|
||||
}
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
// x and c are ignored (u8g2 only)
|
||||
//x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
//c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | 0); // column 0
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b8 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
u8x8_cad_SendData(u8x8, 61, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
|
||||
|
||||
ptr += 61;
|
||||
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | 0); // column 0
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b8 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
u8x8_cad_SendData(u8x8, 61, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 1, NULL);
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8x8_d_sed1520_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
return u8x8_d_sbn1661_122x32(u8x8, msg, arg_int, arg_ptr);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
|
||||
u8x8_d_sed1330.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, olikraus@gmail.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
The device might also work with the RA8835, SED1335 and SED1336 controller.
|
||||
The following devices might be compatible:
|
||||
RA8835
|
||||
SED1330
|
||||
SED1335
|
||||
S1D13700
|
||||
|
||||
|
||||
*/
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_sed1330_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x040, 0x030), /* sys init (0x040) with one arg, where 0x030 is a wild guess */
|
||||
U8X8_CA(0x059, 0x004), /* send display on command (hex 0x059, see p37 ) */
|
||||
/* display cmd has one arg: 01010100 should enable all three blocks, but disable the cursor*/
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_sed1330_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x058, 0x000), /* send display off command (hex 0x059, see p37) and turn of all banks */
|
||||
/* maybe send a sleep in cmd */
|
||||
//U8X8_C(0x053) /* sleep in: 0x053 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_sed1330_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t c, i;
|
||||
uint16_t y;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
|
||||
/*
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
y*=8;
|
||||
y*= u8x8->display_info->tile_width;
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
u8x8_cad_SendCmd(u8x8, 0x046 ); /* CSRW command*/
|
||||
u8x8_cad_SendArg(u8x8, y&255); /* CSRW low adr byte */
|
||||
u8x8_cad_SendArg(u8x8, y>>8); /* CSRW high adr byte */
|
||||
u8x8_cad_SendCmd(u8x8, 0x042 ); /* MWRITE */
|
||||
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes, send one line of data */
|
||||
|
||||
ptr += u8x8->display_info->tile_width;
|
||||
y += u8x8->display_info->tile_width;
|
||||
}
|
||||
|
||||
/* sometimes the display switches off... so just sent a display on command */
|
||||
u8x8_cad_SendCmd(u8x8, 0x059 ); /* display on */
|
||||
u8x8_cad_SendArg(u8x8, 0x004); /* arg for display on */
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=============================================*/
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_sed1330_240x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 30, /* G242CX Datasheet p5 */
|
||||
/* pre_chip_disable_wait_ns = */ 10, /* G242CX Datasheet p5 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140,
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0,
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 120, /* G242CX Datasheet p5 */
|
||||
/* write_pulse_width_ns = */ 220, /* G242CX Datasheet p5 */
|
||||
/* tile_width = */ 0x01e,
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
/* 240x128 Seiko G242C */
|
||||
static const uint8_t u8x8_d_sed1330_240x128_init_seq[] = {
|
||||
U8X8_DLY(100),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(100),
|
||||
|
||||
/* system init command, see also u8x8_d_sed1330_powersave0_seq */
|
||||
U8X8_CA(0x040, 0x030), /* sys init (0x040) with one arg, where 0x030 is a wild guess */
|
||||
/* system init has total 8 parameters, so 7 more are here */
|
||||
U8X8_A(0x087), /* no idea here... WF (topmost bit) is set to one because it is suggested in the datasheet, lowest 3 bits refer to text mode only */
|
||||
U8X8_A(0x007), /* FY: height of a char+1, does not matter here (hopefully), because we use graphics mode only */
|
||||
U8X8_A(0x01d), /* C/R: this could be the number of horizontal bytes - 1 (Value confirmed with app notes p41) */
|
||||
U8X8_A(0x050), /* TC/R: According to app notes fOSC=6Mhz fFF=70Hz --> TC/R = 74d*/
|
||||
U8X8_A(0x080), /* L/F: Lines per frame - 1, probably this is the height of the display - 1 (value confirmed with app notes p41)*/
|
||||
U8X8_A(0x01e), /* Low byte of the virtual screen size. (Value confirmed with app notes p41) */
|
||||
U8X8_A(0), /* High byte of the virtual screen size, see also section 9.1.2 */
|
||||
|
||||
U8X8_C(0x044), /* SCROLL */
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x080),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x040),
|
||||
U8X8_A(0x080),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
|
||||
U8X8_CA(0x05a, 0), /* HDOT SCR: Horizontal dotwise scroll... set to 0 */
|
||||
|
||||
U8X8_CA(0x05b, 0x0c), /* OVLAY: 2-layer, all graphics, OR between layer 1 and 2 */
|
||||
|
||||
|
||||
U8X8_DLY(100),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_DLY(100),
|
||||
};
|
||||
|
||||
/* RA8835 NHD-240128BZ */
|
||||
static const uint8_t u8x8_d_rh8835_nhd_240128_init_seq[] = {
|
||||
U8X8_DLY(100),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(100),
|
||||
|
||||
/* system init command, see also u8x8_d_sed1330_powersave0_seq */
|
||||
U8X8_CA(0x040, 0x030), /* sys init (0x040) with one arg, where 0x030 is a wild guess */
|
||||
/* system init has total 8 parameters, so 7 more are here */
|
||||
U8X8_A(0x087), /* no idea here... WF (topmost bit) is set to one because it is suggested in the datasheet, lowest 3 bits refer to text mode only */
|
||||
U8X8_A(0x007), /* FY: height of a char+1, does not matter here (hopefully), because we use graphics mode only */
|
||||
U8X8_A(0x01d), /* C/R: this could be the number of horizontal bytes - 1 (Value confirmed with app notes p41) */
|
||||
U8X8_A(0x050), /* TC/R: According to app notes fOSC=6Mhz fFF=70Hz --> TC/R = 74d*/
|
||||
U8X8_A(0x080), /* L/F: Lines per frame - 1, probably this is the height of the display - 1 (value confirmed with app notes p41)*/
|
||||
U8X8_A(0x01e), /* Low byte of the virtual screen size. (Value confirmed with app notes p41) */
|
||||
U8X8_A(0), /* High byte of the virtual screen size, see also section 9.1.2 */
|
||||
|
||||
U8X8_C(0x044), /* SCROLL */
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x080),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x040),
|
||||
U8X8_A(0x080),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
|
||||
//U8X8_CA(0x05a, 0), /* HDOT SCR: Horizontal dotwise scroll... set to 0 */
|
||||
|
||||
U8X8_CA(0x05b, 0x0c), /* OVLAY: 2-layer, all graphics, OR between layer 1 and 2 */
|
||||
|
||||
//U8X8_CA(0x059, 0x04), /* send display on command (hex 0x059, see p37 ) */
|
||||
|
||||
U8X8_DLY(100),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_DLY(100),
|
||||
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_sed1330_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sed1330_240x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_240x128_init_seq);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t u8x8_d_ra8835_nhd_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sed1330_240x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_rh8835_nhd_240128_init_seq);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_sed1330_320x240_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 30, /* G242CX Datasheet p5 */
|
||||
/* pre_chip_disable_wait_ns = */ 10, /* G242CX Datasheet p5 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140,
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0,
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 120, /* G242CX Datasheet p5 */
|
||||
/* write_pulse_width_ns = */ 220, /* G242CX Datasheet p5 */
|
||||
/* tile_width = */ 40,
|
||||
/* tile_hight = */ 30,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 320,
|
||||
/* pixel_height = */ 240
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_sed1330_320x240_init_seq[] = {
|
||||
U8X8_DLY(100),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(100),
|
||||
|
||||
/* system init command, see also u8x8_d_sed1330_powersave0_seq */
|
||||
U8X8_CA(0x040, 0x030), /* sys init (0x040) with one arg, where 0x030 is a wild guess */
|
||||
/* system init has total 8 parameters, so 7 more are here */
|
||||
U8X8_A(0x087), /* no idea here... WF (topmost bit) is set to one because it is suggested in the datasheet, lowest 3 bits refer to text mode only */
|
||||
U8X8_A(0x007), /* FY: height of a char+1, does not matter here (hopefully), because we use graphics mode only */
|
||||
U8X8_A(0x027), /* 40-1 */ /* C/R: this could be the number of horizontal bytes - 1 (Value confirmed with app notes p41) */
|
||||
U8X8_A(0x039), /* TC/R: According to app notes fOSC=6Mhz fFF=70Hz --> TC/R = 74d*/
|
||||
U8X8_A(0x0ef), /* L/F: Lines per frame - 1, probably this is the height of the display - 1 (value confirmed with app notes p41)*/
|
||||
U8X8_A(0x028), /* Low byte of the virtual screen size. (Value confirmed with app notes p41) */
|
||||
U8X8_A(0), /* High byte of the virtual screen size, see also section 9.1.2 */
|
||||
|
||||
U8X8_C(0x044), /* SCROLL */
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x0ef),
|
||||
U8X8_A(0x0b0),
|
||||
U8X8_A(0x004),
|
||||
U8X8_A(0x0ef),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
U8X8_A(0x000),
|
||||
|
||||
U8X8_CA(0x05a, 0), /* HDOT SCR: Horizontal dotwise scroll... set to 0 */
|
||||
|
||||
U8X8_CA(0x05b, 0x0c), /* OVLAY: 2-layer, all graphics, OR between layer 1 and 2 */
|
||||
|
||||
|
||||
U8X8_DLY(100),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_DLY(100),
|
||||
};
|
||||
|
||||
|
||||
|
||||
uint8_t u8x8_d_ra8835_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sed1330_320x240_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_320x240_init_seq);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1305.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1305_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1305_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1305_128x32_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0d3, 32), /* display offset to 32 */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1305_128x32_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0d3, 0), /* display offset to */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1305_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendArg(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos) );
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
/*
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 8, ptr);
|
||||
ptr += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
*/
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_powersave1_seq);
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1305 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* timing from SSD1306 */
|
||||
static const u8x8_display_info_t u8x8_ssd1305_128x32_noname_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 2,
|
||||
/* flipmode_x_offset = */ 2,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1305_128x32_noname_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||
U8X8_CA(0x0d3, 32), /* display offset to 32 */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||
|
||||
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
|
||||
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
|
||||
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
|
||||
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_ssd1305_128x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
|
||||
if ( u8x8_d_ssd1305_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_noname_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1305_128x32_noname_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1306_128x32.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
/* UG-2832HSWEG02 Datasheet, Section 4.4 */
|
||||
static const uint8_t u8x8_d_ssd1306_128x32_univision_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x01f), /* multiplex ratio */
|
||||
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x002), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||
U8X8_CA(0x081, 0x08f), /* [2] set contrast control */
|
||||
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
|
||||
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_128x32_univision_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_128x32_univision_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_128x32_univision_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_128x32_univision_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1306_128x32_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x32_univision_display_info);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
/*
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 8, ptr);
|
||||
ptr += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
*/
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1306_128x32_univision_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1306_128x32_univision(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x32_univision_display_info);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1306_128x32_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1306_128x64_noname.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
/* more or less generic setup of all these small OLEDs */
|
||||
static const uint8_t u8x8_d_ssd1306_128x64_noname_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, SSD1306 only, should be removed for SH1106 */
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||
|
||||
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
|
||||
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
|
||||
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
|
||||
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
/* this setup maximizes the brightness range, that can be set with setContrast() */
|
||||
/* Drawback: VCOMH deselect level is set to 0, which das not work so good with all OLEDs, issue #116 */
|
||||
static const uint8_t u8x8_d_ssd1306_128x64_vcomh0_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||
U8X8_CA(0x081, 0x0ef), /* [2] set contrast control, */
|
||||
U8X8_CA(0x0d9, 0x0a1), /* [2] pre-charge period 0x022/f1*/
|
||||
U8X8_CA(0x0db, 0x000), /* vcomh deselect level 0x000 .. 0x070, low nibble always 0 */
|
||||
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/* same as u8x8_d_ssd1306_128x64_noname_init_seq, but 0x0da bit 4 is set to 0 */
|
||||
/* this will disable the alternative COM configuration */
|
||||
static const uint8_t u8x8_d_ssd1306_128x64_alt0_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, SSD1306 only, should be removed for SH1106 */
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x002), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||
|
||||
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
|
||||
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
|
||||
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
|
||||
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* issue 316: a special sh1106 setup, https://www.mikrocontroller.net/topic/431371?goto=5087807#5087807 */
|
||||
static const uint8_t u8x8_d_sh1106_128x64_winstar_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0xae), // Display OFF/ON: off (POR = 0xae)
|
||||
U8X8_C(0xa4), // Set Entire Display OFF/ON: off (POR = 0xa4)
|
||||
U8X8_CA(0xd5, 0x50), // Divide Ratio/Oscillator FrequencyData Set: divide ratio = 1 (POR = 1), Oscillator Frequency = +/- 0% (POR = +/- 0%)
|
||||
U8X8_CA(0xa8, 0x3f), // Multiplex Ratio Data Set: 64 (POR = 0x3f, 64)
|
||||
U8X8_CA(0xd3, 0x00), // Display OffsetData Set: 0 (POR = 0x00)
|
||||
U8X8_C(0x40), // Set Display Start Line: 0
|
||||
U8X8_CA(0xad, 0x8b), // DC-DC ON/OFF Mode Set: Built-in DC-DC is used, Normal Display (POR = 0x8b)
|
||||
U8X8_CA(0xd9, 0x22), // Dis-charge/Pre-charge PeriodData Set: pre-charge 2 DCLKs, dis-charge 2 DCLKs (POR = 0x22, pre-charge 2 DCLKs, dis-charge 2 DCLKs)
|
||||
U8X8_CA(0xdb, 0x35), // VCOM Deselect LevelData Set: 0,770V (POR = 0x35, 0,770 V)
|
||||
U8X8_C(0x32), // Set Pump voltage value: 8,0 V (POR = 0x32, 8,0 V)
|
||||
U8X8_CA(0x81, 0xff), // Contrast Data Register Set: 255 (large) (POR = 0x80)
|
||||
U8X8_C(0x0a6), // Set Normal/Reverse Display: normal (POR = 0xa6)
|
||||
U8X8_CA(0x0da, 0x012), // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5)
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_128x64_noname_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_128x64_noname_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_128x64_noname_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_128x64_noname_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1306_sh1106_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||
break;
|
||||
*/
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendArg(u8x8, 0x000 | ((x&15))); /* probably wrong, should be SendCmd */
|
||||
u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos)); /* probably wrong, should be SendCmd */
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
/*
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 8, ptr);
|
||||
ptr += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
*/
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1306_128x64_noname_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
|
||||
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8x8_d_ssd1306_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
|
||||
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_vcomh0_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8x8_d_ssd1306_128x64_alt0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
|
||||
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_alt0_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_sh1106_128x64_noname_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
|
||||
/* spi_mode = */ 3, /* active low (clock is high by default), rising edge, this seems to be a difference to the ssd1306 */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 2,
|
||||
/* flipmode_x_offset = */ 2,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_sh1106_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
/* maybe use a better init sequence */
|
||||
/* https://www.mikrocontroller.net/topic/431371 */
|
||||
/* the new sequence is added in the winstar constructor (see below), this is kept untouched */
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
uint8_t u8x8_d_sh1106_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_vcomh0_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
uint8_t u8x8_d_sh1106_128x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_128x64_winstar_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1306_64x32.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x32_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x32_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x32_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x32_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1306_64x32_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x32_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_noname_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*======================================================*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1306_64x32_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 8,
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 32,
|
||||
/* flipmode_x_offset = */ 32,
|
||||
/* pixel_width = */ 64,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
|
||||
/*======================================================*/
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x32_noname_init_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x02f), /* multiplex ratio: changed from 0x1f to 0x2f */
|
||||
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1 */
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control datasheet: 0xcf */
|
||||
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1 */
|
||||
U8X8_CA(0x0db, 0x000), /* vcomh deselect level */
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1306_64x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x32_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_noname_init_seq);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1306_64x32_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
/*======================================================*/
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x32_1f_init_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x01f), /* multiplex ratio: changed from 0x1f to 0x2f, 23 Sep 17: changed back to 1f */
|
||||
U8X8_CA(0x0d3, 0x000), /* display offset */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1 */
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control datasheet: 0xcf */
|
||||
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1 */
|
||||
U8X8_CA(0x0db, 0x000), /* vcomh deselect level */
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1306_64x32_1f(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x32_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_1f_init_seq);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1306_64x32_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1306_64x48.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
/* EastRising 0.66 OLED */
|
||||
static const uint8_t u8x8_d_ssd1306_64x48_er_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x02f), /* multiplex ratio, 0.66 OLED: changed from 0x1f to 0x2f */
|
||||
U8X8_CA(0x0d3, 0x000), /* display offset, 0.66 OLED */
|
||||
U8X8_C(0x040), /* set display start line to 0, 0.66 OLED */
|
||||
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, 0.66 OLED 0x14*/
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1, 0.66 OLED */
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse, 0.66 OLED */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 0.66 OLED */
|
||||
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control, 0.66 OLED datasheet: 0xcf */
|
||||
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1, 0.66 OLED datasheet: 0x22 */
|
||||
U8X8_CA(0x0db, 0x000), /* vcomh deselect level, 0.66 OLED datasheet: 0x00 */
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x48_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x48_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x48_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_64x48_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1306_64x48_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x48_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_er_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1306_64x48_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 8,
|
||||
/* tile_hight = */ 6,
|
||||
/* default_x_offset = */ 32,
|
||||
/* flipmode_x_offset = */ 32,
|
||||
/* pixel_width = */ 64,
|
||||
/* pixel_height = */ 48
|
||||
};
|
||||
|
||||
/* East Rising 0.66" OLED */
|
||||
uint8_t u8x8_d_ssd1306_64x48_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x48_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_er_init_seq);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1306_64x48_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1306_96x16.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
/* EastRising 0.69 OLED */
|
||||
static const uint8_t u8x8_d_ssd1306_96x16_er_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
U8X8_CA(0x0a8, 0x00f), /* multiplex ratio, 0.69 OLED: 0x0f */
|
||||
U8X8_CA(0x0d3, 0x000), /* display offset, 0.69 OLED */
|
||||
U8X8_C(0x040), /* set display start line to 0, 0.69 OLED */
|
||||
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, 0.66 OLED 0x14*/
|
||||
U8X8_CA(0x020, 0x000), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1, 0.66 OLED */
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse, 0.66 OLED */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x002), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 0.66 OLED */
|
||||
U8X8_CA(0x081, 0x0af), /* [2] set contrast control, 0.69 OLED datasheet: 0xaf */
|
||||
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x0f1, 0.69 OLED datasheet: 0xf1 */
|
||||
U8X8_CA(0x0db, 0x020), /* vcomh deselect level, 0.69 OLED datasheet: 0x20 */
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_96x16_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_96x16_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_96x16_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1306_96x16_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1306_96x16_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_96x16_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_er_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1306_96x16_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 12,
|
||||
/* tile_hight = */ 2,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 32,
|
||||
/* pixel_width = */ 96,
|
||||
/* pixel_height = */ 16
|
||||
};
|
||||
|
||||
/* East Rising 0.69" OLED */
|
||||
uint8_t u8x8_d_ssd1306_96x16_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_96x16_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_er_init_seq);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1306_96x16_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1309.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1309_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1309_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1309_128x64_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1309_128x64_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1309_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendArg(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos) );
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
/*
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 8, ptr);
|
||||
ptr += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
*/
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_powersave1_seq);
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1309 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=================================================*/
|
||||
/* offset 2 version */
|
||||
|
||||
/* timing from SSD1306 */
|
||||
static const u8x8_display_info_t u8x8_ssd1309_128x64_noname2_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 2,
|
||||
/* flipmode_x_offset = */ 2,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1309_128x64_noname_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0d5, 0x0a0), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
|
||||
//U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_CA(0x020, 0x002), /* page addressing mode */
|
||||
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
|
||||
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
|
||||
|
||||
U8X8_CA(0x081, 0x06f), /* [2] set contrast control */
|
||||
U8X8_CA(0x0d9, 0x0d3), /* [2] pre-charge period 0x022/f1*/
|
||||
U8X8_CA(0x0db, 0x020), /* vcomh deselect level */
|
||||
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
|
||||
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
|
||||
|
||||
U8X8_C(0x02e), /* Deactivate scroll */
|
||||
U8X8_C(0x0a4), /* output ram to display */
|
||||
U8X8_C(0x0a6), /* none inverted normal display mode */
|
||||
|
||||
//U8X8_C(0x0af), /* display on */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_ssd1309_128x64_noname2(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
|
||||
if ( u8x8_d_ssd1309_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_noname_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1309_128x64_noname2_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*=================================================*/
|
||||
/* offset 0 version */
|
||||
|
||||
/* timing from SSD1306 */
|
||||
static const u8x8_display_info_t u8x8_ssd1309_128x64_noname0_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1309_128x64_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
|
||||
if ( u8x8_d_ssd1309_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_noname_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1309_128x64_noname0_display_info);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1322.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1322_init_seq[] = {
|
||||
|
||||
U8X8_DLY(1),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(1),
|
||||
|
||||
U8X8_CA(0xfd, 0x12), /* unlock */
|
||||
U8X8_C(0xae), /* display off */
|
||||
U8X8_CA(0xb3, 0x91), /* set display clock divide ratio/oscillator frequency (set clock as 80 frames/sec) */
|
||||
U8X8_CA(0xca, 0x3f), /* multiplex ratio 1/64 Duty (0x0F~0x3F) */
|
||||
U8X8_CA(0xa2, 0x00), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0xa1, 0x00), /* display start line */
|
||||
//U8X8_CAA(0xa0, 0x14, 0x11), /* Set Re-Map / Dual COM Line Mode */
|
||||
U8X8_CAA(0xa0, 0x06, 0x011), /* Set Re-Map / Dual COM Line Mode */
|
||||
U8X8_CA(0xab, 0x01), /* Enable Internal VDD Regulator */
|
||||
U8X8_CAA(0xb4, 0xa0, 0x005|0x0fd), /* Display Enhancement A */
|
||||
U8X8_CA(0xc1, 0x9f), /* contrast */
|
||||
U8X8_CA(0xc7, 0x0f), /* Set Scale Factor of Segment Output Current Control */
|
||||
U8X8_C(0xb9), /* linear grayscale */
|
||||
U8X8_CA(0xb1, 0xe2), /* Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment */
|
||||
U8X8_CAA(0xd1, 0x082|0x020, 0x020), /* Display Enhancement B */
|
||||
U8X8_CA(0xbb, 0x1f), /* precharge voltage */
|
||||
U8X8_CA(0xb6, 0x08), /* precharge period */
|
||||
U8X8_CA(0xbe, 0x07), /* vcomh */
|
||||
U8X8_C(0xa6), /* normal display */
|
||||
U8X8_C(0xa9), /* exit partial display */
|
||||
|
||||
|
||||
U8X8_DLY(1), /* delay 2ms */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1322_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* ssd1322: display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1322_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* ssd1322: display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1322_256x64_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CAA(0x0a0, 0x006, 0x011), /* remap */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1322_256x64_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CAA(0x0a0, 0x014, 0x011), /* remap */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/* interpret b as a monochrome bit pattern, write value 15 for high bit and value 0 for a low bit */
|
||||
/* topbit (msb) is sent last */
|
||||
/* example: b = 0x083 will send 0xff, 0x00, 0x00, 0xf0 */
|
||||
|
||||
/* 4 Jan 2017: I think this procedure not required any more. Delete? */
|
||||
uint8_t u8x8_write_byte_to_16gr_device(u8x8_t *u8x8, uint8_t b)
|
||||
{
|
||||
static uint8_t buf[4];
|
||||
static uint8_t map[4] = { 0, 0x00f, 0x0f0, 0x0ff };
|
||||
buf [3] = map[b & 3];
|
||||
b>>=2;
|
||||
buf [2] = map[b & 3];
|
||||
b>>=2;
|
||||
buf [1] = map[b & 3];
|
||||
b>>=2;
|
||||
buf [0] = map[b & 3];
|
||||
return u8x8_cad_SendData(u8x8, 4, buf); /* note: SendData can not handle more than 255 bytes, send one line of data */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
input:
|
||||
one tile (8 Bytes)
|
||||
output:
|
||||
Tile for SSD1325 (32 Bytes)
|
||||
*/
|
||||
|
||||
static uint8_t u8x8_ssd1322_8to32_dest_buf[32];
|
||||
|
||||
static uint8_t *u8x8_ssd1322_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
|
||||
{
|
||||
uint8_t v;
|
||||
uint8_t a,b;
|
||||
uint8_t i, j;
|
||||
uint8_t *dest;
|
||||
|
||||
for( j = 0; j < 4; j++ )
|
||||
{
|
||||
dest = u8x8_ssd1322_8to32_dest_buf;
|
||||
dest += j;
|
||||
a =*ptr;
|
||||
ptr++;
|
||||
b = *ptr;
|
||||
ptr++;
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
v = 0;
|
||||
if ( a&1 ) v |= 0xf0;
|
||||
if ( b&1 ) v |= 0x0f;
|
||||
*dest = v;
|
||||
dest+=4;
|
||||
a >>= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return u8x8_ssd1322_8to32_dest_buf;
|
||||
}
|
||||
|
||||
|
||||
uint8_t u8x8_d_ssd1322_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
|
||||
/*
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x0C1 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1322 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 2; // only every 4th col can be addressed
|
||||
x += u8x8->x_offset;
|
||||
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
y *= 8;
|
||||
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address, moved out of the loop (issue 302) */
|
||||
u8x8_cad_SendArg(u8x8, y);
|
||||
u8x8_cad_SendArg(u8x8, y+7);
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
|
||||
u8x8_cad_SendArg(u8x8, x ); /* start */
|
||||
u8x8_cad_SendArg(u8x8, x+1 ); /* end */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x05c ); /* write to ram */
|
||||
|
||||
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1322_8to32(u8x8, ptr));
|
||||
|
||||
ptr += 8;
|
||||
x += 2;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
//x += 2;
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1322_256x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100, /* SSD1322: 2 us */
|
||||
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1322: 15ns, but cycle time is 100ns, so use 100/2 */
|
||||
/* sck_pulse_width_ns = */ 50, /* SSD1322: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 10000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215), 10 MHz (issue 301) */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 10,
|
||||
/* write_pulse_width_ns = */ 150, /* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
|
||||
/* tile_width = */ 32, /* 256 pixel, so we require 32 bytes for this */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0x01c, /* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
|
||||
/* flipmode_x_offset = */ 0x01c,
|
||||
/* pixel_width = */ 256,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
|
||||
|
||||
uint8_t u8x8_d_ssd1322_nhd_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1322_256x64_display_info);
|
||||
break;
|
||||
|
||||
default:
|
||||
return u8x8_d_ssd1322_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1325.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
/* http://www.newhavendisplay.com/app_notes/OLED_2_7_12864.txt */
|
||||
static const uint8_t u8x8_d_ssd1325_128x64_nhd_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
|
||||
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
|
||||
U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0x0a1, 0x000), /* display start line */
|
||||
U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
|
||||
U8X8_CA(0x0a0, 0x052), /* remap configuration, horizontal address increment (bit 2 = 0), enable nibble remap (upper nibble is left, bit 1 = 1) */
|
||||
U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
|
||||
U8X8_C(0x0b8), /* set gray scale table */
|
||||
U8X8_A(0x001), /* */
|
||||
U8X8_A(0x011), /* */
|
||||
U8X8_A(0x022), /* */
|
||||
U8X8_A(0x032), /* */
|
||||
U8X8_A(0x043), /* */
|
||||
U8X8_A(0x054), /* */
|
||||
U8X8_A(0x065), /* */
|
||||
U8X8_A(0x076), /* */
|
||||
|
||||
U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128, Newhaven: 0x040 */
|
||||
U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
|
||||
U8X8_CA(0x0b1, 0x055), /* phase length */
|
||||
U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
|
||||
U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
|
||||
U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
U8X8_C(0x0a4), /* normal display mode */
|
||||
|
||||
U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1325_128x64_nhd_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1325_128x64_nhd_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1325_128x64_nhd_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a0, 0x052), /* remap */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1325_128x64_nhd_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a0, 0x041), /* remap */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
input:
|
||||
one tile (8 Bytes)
|
||||
output:
|
||||
Tile for SSD1325 (32 Bytes)
|
||||
*/
|
||||
|
||||
static uint8_t u8x8_ssd1325_8to32_dest_buf[32];
|
||||
|
||||
static uint8_t *u8x8_ssd1325_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
|
||||
{
|
||||
uint8_t v;
|
||||
uint8_t a,b;
|
||||
uint8_t i, j;
|
||||
uint8_t *dest;
|
||||
|
||||
for( j = 0; j < 4; j++ )
|
||||
{
|
||||
dest = u8x8_ssd1325_8to32_dest_buf;
|
||||
dest += j;
|
||||
a =*ptr;
|
||||
ptr++;
|
||||
b = *ptr;
|
||||
ptr++;
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
v = 0;
|
||||
if ( a&1 ) v |= 0xf0;
|
||||
if ( b&1 ) v |= 0x0f;
|
||||
*dest = v;
|
||||
dest+=4;
|
||||
a >>= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return u8x8_ssd1325_8to32_dest_buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1325_128x64_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1325_128x64_nhd_display_info);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1325 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 4;
|
||||
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
y *= 8;
|
||||
y += u8x8->x_offset; /* x_offset is used as y offset for the SSD1325 */
|
||||
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address */
|
||||
u8x8_cad_SendArg(u8x8, y);
|
||||
u8x8_cad_SendArg(u8x8, y+7);
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
|
||||
do
|
||||
{
|
||||
if ( ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] | ptr[7] )
|
||||
{
|
||||
/* draw the tile if pattern is not zero for all bytes */
|
||||
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
|
||||
u8x8_cad_SendArg(u8x8, x ); /* start */
|
||||
u8x8_cad_SendArg(u8x8, x+3 ); /* end */
|
||||
|
||||
|
||||
|
||||
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1325_8to32(u8x8, ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* tile is empty, use the graphics acceleration command */
|
||||
u8x8_cad_SendCmd(u8x8, 0x024 ); // draw rectangle
|
||||
u8x8_cad_SendArg(u8x8, x );
|
||||
u8x8_cad_SendArg(u8x8, y );
|
||||
u8x8_cad_SendArg(u8x8, x+3 );
|
||||
u8x8_cad_SendArg(u8x8, y+7 );
|
||||
u8x8_cad_SendArg(u8x8, 0 ); // clear
|
||||
}
|
||||
ptr += 8;
|
||||
x += 4;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
//x += 4;
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_nhd_ssd1325_128x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100, /**/
|
||||
/* sda_setup_time_ns = */ 100, /* SSD1325 */
|
||||
/* sck_pulse_width_ns = */ 100, /* SSD1325 */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 60, /* SSD1325 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0, /* x_offset is used as y offset for the SSD1325 */
|
||||
/* flipmode_x_offset = */ 8, /* x_offset is used as y offset for the SSD1325 */
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1325_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_nhd_ssd1325_128x64_display_info);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1325_128x64_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1326.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
/* ER OLED */
|
||||
static const uint8_t u8x8_d_ssd1326_er_256x32_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_CA(0x0fd, 0x012), /* unlock (not required, this is default by reset) */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0a8, 0x01f), /* multiplex ratio: 0x03f * 1/64 duty - changed by CREESOO, acc. to datasheet, 100317*/
|
||||
U8X8_CA(0x0a1, 0x000), /* display start line */
|
||||
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
|
||||
//U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
|
||||
U8X8_CA(0x0a0, 0x052), /* remap configuration, horizontal address increment (bit 2 = 0), enable nibble remap (upper nibble is left, bit 1 = 1) */
|
||||
U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
|
||||
|
||||
U8X8_C(0x0b7), /* set default gray scale table */
|
||||
|
||||
U8X8_CA(0x081, 0x027), /* contrast, brightness, 0..128 */
|
||||
U8X8_CA(0x0b1, 0x071), /* phase length */
|
||||
//U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
|
||||
U8X8_CA(0x0b3, 0x0f0), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
|
||||
//U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
//U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
U8X8_CAA(0x0bb, 0x035, 0x0ff), /* set precharge */
|
||||
U8X8_CA(0x0bc, 0x01f), /* pre-charge voltage level */
|
||||
U8X8_CA(0x0be, 0x00f), /* VCOMH voltage */
|
||||
U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
U8X8_C(0x0a4), /* normal display mode */
|
||||
|
||||
//U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1326_256x32_nhd_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1326_256x32_nhd_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1326_256x32_nhd_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a0, 0x052), /* remap */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1326_256x32_nhd_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a0, 0x041), /* remap */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
input:
|
||||
one tile (8 Bytes)
|
||||
output:
|
||||
Tile for ssd1326 (32 Bytes)
|
||||
*/
|
||||
|
||||
static uint8_t u8x8_ssd1326_8to32_dest_buf[32];
|
||||
|
||||
static uint8_t *u8x8_ssd1326_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
|
||||
{
|
||||
uint8_t v;
|
||||
uint8_t a,b;
|
||||
uint8_t i, j;
|
||||
uint8_t *dest;
|
||||
|
||||
for( j = 0; j < 4; j++ )
|
||||
{
|
||||
dest = u8x8_ssd1326_8to32_dest_buf;
|
||||
dest += j;
|
||||
a =*ptr;
|
||||
ptr++;
|
||||
b = *ptr;
|
||||
ptr++;
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
v = 0;
|
||||
if ( a&1 ) v |= 0xf0;
|
||||
if ( b&1 ) v |= 0x0f;
|
||||
*dest = v;
|
||||
dest+=4;
|
||||
a >>= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return u8x8_ssd1326_8to32_dest_buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1326_256x32_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1326_256x32_nhd_display_info);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_er_256x32_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_256x32_nhd_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_256x32_nhd_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_256x32_nhd_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_256x32_nhd_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1326 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 4;
|
||||
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
|
||||
y *= 8;
|
||||
y += u8x8->x_offset; /* x_offset is used as y offset for the ssd1326 */
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
|
||||
do
|
||||
{
|
||||
/* tile is empty, use the graphics acceleration command */
|
||||
/* are this really available on the ssd1326??? */
|
||||
u8x8_cad_SendCmd(u8x8, 0x024 ); // draw rectangle
|
||||
u8x8_cad_SendArg(u8x8, x );
|
||||
u8x8_cad_SendArg(u8x8, y );
|
||||
u8x8_cad_SendArg(u8x8, x+3 );
|
||||
u8x8_cad_SendArg(u8x8, y+7 );
|
||||
u8x8_cad_SendArg(u8x8, 0 ); // clear
|
||||
ptr += 8;
|
||||
x += 4;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
//x += 4;
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1326_256x32_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 15,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100, /**/
|
||||
/* sda_setup_time_ns = */ 100, /* ssd1326 */
|
||||
/* sck_pulse_width_ns = */ 100, /* ssd1326 */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 60, /* ssd1326 */
|
||||
/* tile_width = */ 32,
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 0, /* x_offset is used as y offset for the ssd1326 */
|
||||
/* flipmode_x_offset = */ 0, /* x_offset is used as y offset for the ssd1326 */
|
||||
/* pixel_width = */ 256,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1326_er_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1326_256x32_display_info);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1326_256x32_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1327.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1327_96x96_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1327_96x96_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
input:
|
||||
one tile (8 Bytes)
|
||||
output:
|
||||
Tile for ssd1327 (32 Bytes)
|
||||
*/
|
||||
|
||||
static uint8_t u8x8_ssd1327_8to32_dest_buf[32];
|
||||
|
||||
static uint8_t *u8x8_ssd1327_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
|
||||
{
|
||||
uint8_t v;
|
||||
uint8_t a,b;
|
||||
uint8_t i, j;
|
||||
uint8_t *dest;
|
||||
|
||||
for( j = 0; j < 4; j++ )
|
||||
{
|
||||
dest = u8x8_ssd1327_8to32_dest_buf;
|
||||
dest += j;
|
||||
a =*ptr;
|
||||
ptr++;
|
||||
b = *ptr;
|
||||
ptr++;
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
v = 0;
|
||||
if ( a&1 ) v |= 0xf0;
|
||||
if ( b&1 ) v |= 0x0f;
|
||||
*dest = v;
|
||||
dest+=4;
|
||||
a >>= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return u8x8_ssd1327_8to32_dest_buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1327_96x96_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_96x96_display_info);
|
||||
break;
|
||||
*/
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_powersave1_seq);
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1327 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 4;
|
||||
x+=u8x8->x_offset/2;
|
||||
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
y *= 8;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address, moved out of the loop (issue 302) */
|
||||
u8x8_cad_SendArg(u8x8, y);
|
||||
u8x8_cad_SendArg(u8x8, y+7);
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
|
||||
u8x8_cad_SendArg(u8x8, x ); /* start */
|
||||
u8x8_cad_SendArg(u8x8, x+3 ); /* end */
|
||||
|
||||
|
||||
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1327_8to32(u8x8, ptr));
|
||||
ptr += 8;
|
||||
x += 4;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
//x += 4;
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=============================================*/
|
||||
/* Seeedstudio Grove OLED 96x96 */
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1327_96x96_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100, /**/
|
||||
/* sda_setup_time_ns = */ 100, /* */
|
||||
/* sck_pulse_width_ns = */ 100, /* */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 1, /* use 1 instead of 4, because the SSD1327 seems to be very slow */
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 60,
|
||||
/* tile_width = */ 12,
|
||||
/* tile_hight = */ 12,
|
||||
/* default_x_offset = */ 16,
|
||||
/* flipmode_x_offset = */ 16,
|
||||
/* pixel_width = */ 96,
|
||||
/* pixel_height = */ 96
|
||||
};
|
||||
|
||||
/* https://github.com/SeeedDocument/Grove_OLED_1.12/raw/master/resources/LY120-096096.pdf */
|
||||
/* http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96 */
|
||||
/* values from u8glib */
|
||||
/*
|
||||
Re-map setting in Graphic Display Data RAM, command 0x0a0
|
||||
Bit 0: Column Address Re-map
|
||||
Bit 1: Nibble Re-map
|
||||
Bit 2: Horizontal/Vertical Address Increment
|
||||
Bit 3: Not used, must be 0
|
||||
|
||||
Bit 4: COM Re-map
|
||||
Bit 5: Not used, must be 0
|
||||
Bit 6: COM Split Odd Even
|
||||
Bit 7: Not used, must be 0
|
||||
*/
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1327_96x96_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_CA(0x0fd, 0x012), /* unlock display, usually not required because the display is unlocked after reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
//U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
|
||||
U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x05f * 1/64 duty */
|
||||
U8X8_CA(0x0a1, 0x000), /* display start line */
|
||||
//U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */
|
||||
|
||||
U8X8_CA(0x0a2, 0x020), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0x0a0, 0x051), /* remap configuration */
|
||||
|
||||
|
||||
U8X8_CA(0x0ab, 0x001), /* Enable internal VDD regulator (RESET) */
|
||||
//U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */
|
||||
U8X8_CA(0x081, 0x053), /* contrast, brightness, 0..128 */
|
||||
//U8X8_CA(0x0b1, 0x055), /* phase length */
|
||||
U8X8_CA(0x0b1, 0x051), /* phase length */
|
||||
//U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
|
||||
U8X8_CA(0x0b3, 0x001), /* set display clock divide ratio/oscillator frequency */
|
||||
|
||||
//? U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
|
||||
//? U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
|
||||
|
||||
U8X8_C(0x0b9), /* use linear lookup table */
|
||||
|
||||
//U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
|
||||
U8X8_CA(0x0bc, 0x008), /* pre-charge voltage level */
|
||||
//U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
|
||||
U8X8_CA(0x0be, 0x007), /* VCOMH voltage */
|
||||
U8X8_CA(0x0b6, 0x001), /* second precharge */
|
||||
U8X8_CA(0x0d5, 0x062), /* enable second precharge, internal vsl (bit0 = 0) */
|
||||
|
||||
|
||||
|
||||
U8X8_C(0x0a4), /* normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1327_seeed_96x96_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a2, 0x020), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0x0a0, 0x051), /* remap configuration */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1327_seeed_96x96_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a2, 0x060), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0x0a0, 0x042), /* remap configuration */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_ssd1327_seeed_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_96x96_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_init_seq);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
|
||||
{
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_seeed_96x96_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_seeed_96x96_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
/* MIDAS MCOT128128C1V-YM 128x128 Module */
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1327_128x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 10,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100, /**/
|
||||
/* sda_setup_time_ns = */ 100, /* */
|
||||
/* sck_pulse_width_ns = */ 100, /* */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 1, /* use 1 instead of 4, because the SSD1327 seems to be very slow */
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 60,
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
/* https://github.com/SeeedDocument/Grove_OLED_1.12/raw/master/resources/LY120-096096.pdf */
|
||||
/* http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96 */
|
||||
/* values from u8glib */
|
||||
/*
|
||||
Re-map setting in Graphic Display Data RAM, command 0x0a0
|
||||
Bit 0: Column Address Re-map
|
||||
Bit 1: Nibble Re-map
|
||||
Bit 2: Horizontal/Vertical Address Increment
|
||||
Bit 3: Not used, must be 0
|
||||
|
||||
Bit 4: COM Re-map
|
||||
Bit 5: Not used, must be 0
|
||||
Bit 6: COM Split Odd Even
|
||||
Bit 7: Not used, must be 0
|
||||
*/
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1327_128x128_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_CA(0x0fd, 0x012), /* unlock display, usually not required because the display is unlocked after reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
//U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
|
||||
//U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x05f * 1/64 duty */
|
||||
U8X8_CA(0x0a8, 0x07f), /* multiplex ratio: 0x05f * 1/128duty */
|
||||
U8X8_CA(0x0a1, 0x000), /* display start line */
|
||||
//U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */
|
||||
|
||||
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0x0a0, 0x051), /* remap configuration */
|
||||
|
||||
|
||||
U8X8_CA(0x0ab, 0x001), /* Enable internal VDD regulator (RESET) */
|
||||
//U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */
|
||||
U8X8_CA(0x081, 0x053), /* contrast, brightness, 0..128 */
|
||||
//U8X8_CA(0x0b1, 0x055), /* phase length */
|
||||
U8X8_CA(0x0b1, 0x051), /* phase length */
|
||||
//U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
|
||||
U8X8_CA(0x0b3, 0x001), /* set display clock divide ratio/oscillator frequency */
|
||||
|
||||
//? U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
|
||||
//? U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
|
||||
|
||||
U8X8_C(0x0b9), /* use linear lookup table */
|
||||
|
||||
//U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
|
||||
U8X8_CA(0x0bc, 0x008), /* pre-charge voltage level */
|
||||
//U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
|
||||
U8X8_CA(0x0be, 0x007), /* VCOMH voltage */
|
||||
U8X8_CA(0x0b6, 0x001), /* second precharge */
|
||||
U8X8_CA(0x0d5, 0x062), /* enable second precharge, internal vsl (bit0 = 0) */
|
||||
|
||||
|
||||
|
||||
U8X8_C(0x0a4), /* normal display mode */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1327_128x128_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0x0a0, 0x051), /* remap configuration */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1327_128x128_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0x0a0, 0x042), /* remap configuration */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_ssd1327_midas_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call the 96x96 procedure at the moment */
|
||||
if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_128x128_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_init_seq);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
|
||||
{
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1329.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1329_128x96_noname_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
|
||||
U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x03f * 1/64 duty - changed by CREESOO, acc. to datasheet, 100317*/
|
||||
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
|
||||
U8X8_CA(0x0a1, 0x000), /* display start line */
|
||||
U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
|
||||
U8X8_CA(0x0a0, 0x052), /* remap configuration, horizontal address increment (bit 2 = 0), enable nibble remap (upper nibble is left, bit 1 = 1) */
|
||||
U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
|
||||
#ifdef removed
|
||||
U8X8_C(0x0b8), /* set gray scale table */
|
||||
U8X8_A(1), /* */
|
||||
U8X8_A(5), /* */
|
||||
U8X8_A(10), /* */
|
||||
U8X8_A(14), /* */
|
||||
U8X8_A(19), /* */
|
||||
U8X8_A(23), /* */
|
||||
U8X8_A(28), /* */
|
||||
U8X8_A(32), /* */
|
||||
U8X8_A(37), /* */
|
||||
U8X8_A(41), /* */
|
||||
U8X8_A(46), /* */
|
||||
U8X8_A(50), /* */
|
||||
U8X8_A(55), /* */
|
||||
U8X8_A(59), /* */
|
||||
U8X8_A(63), /* */
|
||||
#endif
|
||||
|
||||
U8X8_C(0x0b7), /* set default gray scale table */
|
||||
|
||||
U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */
|
||||
U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
|
||||
U8X8_CA(0x0b1, 0x055), /* phase length */
|
||||
U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
|
||||
U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
|
||||
U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
|
||||
U8X8_C(0x0a4), /* normal display mode */
|
||||
|
||||
U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1329_128x96_nhd_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1329_128x96_nhd_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1329_128x96_nhd_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a0, 0x052), /* remap */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1329_128x96_nhd_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0a0, 0x041), /* remap */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
input:
|
||||
one tile (8 Bytes)
|
||||
output:
|
||||
Tile for ssd1329 (32 Bytes)
|
||||
*/
|
||||
|
||||
static uint8_t u8x8_ssd1329_8to32_dest_buf[32];
|
||||
|
||||
static uint8_t *u8x8_ssd1329_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
|
||||
{
|
||||
uint8_t v;
|
||||
uint8_t a,b;
|
||||
uint8_t i, j;
|
||||
uint8_t *dest;
|
||||
|
||||
for( j = 0; j < 4; j++ )
|
||||
{
|
||||
dest = u8x8_ssd1329_8to32_dest_buf;
|
||||
dest += j;
|
||||
a =*ptr;
|
||||
ptr++;
|
||||
b = *ptr;
|
||||
ptr++;
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
v = 0;
|
||||
if ( a&1 ) v |= 0xf0;
|
||||
if ( b&1 ) v |= 0x0f;
|
||||
*dest = v;
|
||||
dest+=4;
|
||||
a >>= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return u8x8_ssd1329_8to32_dest_buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1329_128x96_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1329_128x96_nhd_display_info);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_noname_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_nhd_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_nhd_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_nhd_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_nhd_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1329 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 4;
|
||||
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
|
||||
y *= 8;
|
||||
y += u8x8->x_offset; /* x_offset is used as y offset for the ssd1329 */
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
|
||||
do
|
||||
{
|
||||
if ( ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] | ptr[7] )
|
||||
{
|
||||
/* draw the tile if pattern is not zero for all bytes */
|
||||
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
|
||||
u8x8_cad_SendArg(u8x8, x ); /* start */
|
||||
u8x8_cad_SendArg(u8x8, x+3 ); /* end */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address */
|
||||
u8x8_cad_SendArg(u8x8, y);
|
||||
u8x8_cad_SendArg(u8x8, y+7);
|
||||
|
||||
|
||||
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1329_8to32(u8x8, ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* tile is empty, use the graphics acceleration command */
|
||||
/* are this really available on the SSD1329??? */
|
||||
u8x8_cad_SendCmd(u8x8, 0x024 ); // draw rectangle
|
||||
u8x8_cad_SendArg(u8x8, x );
|
||||
u8x8_cad_SendArg(u8x8, y );
|
||||
u8x8_cad_SendArg(u8x8, x+3 );
|
||||
u8x8_cad_SendArg(u8x8, y+7 );
|
||||
u8x8_cad_SendArg(u8x8, 0 ); // clear
|
||||
}
|
||||
ptr += 8;
|
||||
x += 4;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
//x += 4;
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1329_128x96_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 15,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100, /**/
|
||||
/* sda_setup_time_ns = */ 100, /* ssd1329 */
|
||||
/* sck_pulse_width_ns = */ 100, /* ssd1329 */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 60, /* ssd1329 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 12,
|
||||
/* default_x_offset = */ 0, /* x_offset is used as y offset for the ssd1329 */
|
||||
/* flipmode_x_offset = */ 0, /* x_offset is used as y offset for the ssd1329 */
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 96
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1329_128x96_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1329_128x96_display_info);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1329_128x96_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1606_172x72.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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.
|
||||
|
||||
SSD1606: 128x180x2
|
||||
two-bit, four graylevels
|
||||
command
|
||||
0x22: assign actions
|
||||
0x20: execute actions
|
||||
|
||||
action for command 0x022 are (more or less guessed)
|
||||
bit 7: Enable Clock
|
||||
bit 6: Enable Charge Pump
|
||||
bit 5: Load Temparture Value (???)
|
||||
bit 4: Load LUT (???)
|
||||
bit 3: Initial Display (???)
|
||||
bit 2: Pattern Display --> Requires about 945ms with the LUT from below
|
||||
bit 1: Disable Charge Pump
|
||||
bit 0: Disable Clock
|
||||
|
||||
Disable Charge Pump and Clock require about 267ms
|
||||
Enable Charge Pump and Clock require about 10ms
|
||||
|
||||
Notes:
|
||||
- Introduced a refresh display message, which copies RAM to display
|
||||
- Charge pump and clock are only enabled for the transfer RAM to display
|
||||
- U8x8 will not really work because of the two buffers in the SSD1606, however U8g2 should be ok.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
#define L(a,b,c,d) (((a)<<6)|((b)<<4)|((c)<<2)|(d))
|
||||
|
||||
|
||||
/* GDE021A1, 2.1" EPD */
|
||||
static const uint8_t u8x8_d_ssd1606_172x72_gde021a1_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: Disable */
|
||||
U8X8_CA(0x11, 0x03), /* Define data entry mode, x&y inc, x first */
|
||||
U8X8_CAA(0x44, 0, 31), /* RAM x start & end, each byte has 4 pixel, 32*4=128 */
|
||||
U8X8_CAA(0x45, 0, 179), /* RAM y start & end, 179 MAX */
|
||||
|
||||
U8X8_CA(0x4e, 0), /* set x pos, 0..31 */
|
||||
U8X8_CA(0x4f, 0), /* set y pos, 0...179 */
|
||||
|
||||
U8X8_CA(0xf0, 0x1f), /* set booster feedback to internal */
|
||||
U8X8_CA(0x22, 0xc0), /* display update seq. option: enable clk, enable CP, .... todo: this is never activated */
|
||||
|
||||
U8X8_C(0x32), /* write LUT register*/
|
||||
|
||||
#ifdef ORIGINAL_LUT
|
||||
|
||||
/* wavefrom part of the LUT: absolute LUT... this will always force the destination color */
|
||||
U8X8_A4(0x00,0x00,0x00,0x55), /* step 0 */
|
||||
U8X8_A4(0x00,0x00,0x55,0x55), /* step 1 */
|
||||
U8X8_A4(0x00,0x55,0x55,0x55),
|
||||
U8X8_A4(0xAA,0xAA,0xAA,0xAA),
|
||||
U8X8_A4(0x15,0x15,0x15,0x15),
|
||||
U8X8_A4(0x05,0x05,0x05,0x05),
|
||||
U8X8_A4(0x01,0x01,0x01,0x01),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00), /* step 19 */
|
||||
|
||||
/* timing part of the LUT */
|
||||
U8X8_A8(0x22,0xFB,0x22,0x1B,0x00,0x00,0x00,0x00),
|
||||
U8X8_A(0x00),U8X8_A(0x00),
|
||||
|
||||
#else
|
||||
|
||||
/* the following LUT will not change anything if the old and the new values are the same */
|
||||
/* 03 02 01 00 13 12 11 10 23 22 21 20 33 32 31 30 original */
|
||||
U8X8_A4(L(0, 0, 0, 0), L(0, 0, 0, 0), L(0, 0, 0, 0), L(0, 1, 1, 1)), // 0x00,0x00,0x00,0x55, step 0
|
||||
U8X8_A4(L(0, 0, 0, 0), L(0, 0, 0, 0), L(1, 0, 1, 1), L(0, 1, 1, 1)), // 0x00,0x00,0x55,0x55, step 1
|
||||
U8X8_A4(L(0, 0, 0, 0), L(1, 1, 0, 1), L(1, 0, 1, 1), L(0, 1, 1, 1)), // 0x00,0x55,0x55,0x55, step 2
|
||||
U8X8_A4(L(2, 2, 2, 0), L(2, 2, 0, 2), L(2, 0, 2, 2), L(0, 2, 2, 2)), // 0xAA,0xAA,0xAA,0xAA, step 3
|
||||
U8X8_A4(L(0, 1, 1, 0), L(0, 1, 0, 1), L(0, 0, 1, 1), L(0, 1, 1, 1)), // 0x15,0x15,0x15,0x15, step 4
|
||||
U8X8_A4(L(0, 0, 1, 0), L(0, 0, 0, 1), L(0, 0, 1, 1), L(0, 0, 1, 1)), // 0x05,0x05,0x05,0x05, step 5
|
||||
U8X8_A4(L(0, 0, 0, 0), L(0, 0, 0, 1), L(0, 0, 0, 1), L(0, 0, 0, 1)), // 0x01,0x01,0x01,0x01, step 6
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00),
|
||||
U8X8_A4(0x00,0x00,0x00,0x00), /* step 19 */
|
||||
|
||||
/* timing part of the LUT */
|
||||
U8X8_A8(0x22,0xFB,0x22,0x1B,0x00,0x00,0x00,0x00),
|
||||
U8X8_A(0x00),U8X8_A(0x00),
|
||||
|
||||
#endif
|
||||
|
||||
U8X8_CA(0x2c, 0xa0), /* write vcom value*/
|
||||
U8X8_CA(0x3c, 0x63), /* select boarder waveform */
|
||||
U8X8_CA(0x22, 0xc4), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
|
||||
/* 0x0c4 is mentioned in chapter 9.2 of the GDE021A1 data sheet */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1606_to_display_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
|
||||
//U8X8_CA(0x22, 0xc0), /* display update seq. option: Enable clock and charge pump */
|
||||
//U8X8_C(0x20), /* execute sequence */
|
||||
//U8X8_DLY(10),
|
||||
/* strange, splitting 0x0c0 does not work reliable */
|
||||
|
||||
U8X8_CA(0x22, 0xc4), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(250), /* the sequence above requires about 970ms */
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(230),
|
||||
|
||||
U8X8_CA(0x22, 0x03), /* disable clock and charge pump */
|
||||
U8X8_DLY(200), /* this requres about 270ms */
|
||||
U8X8_DLY(90),
|
||||
|
||||
//U8X8_CA(0x10, 0x01), /* deep sleep mode */
|
||||
//U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1606_172x72_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1606_172x72_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1606_172x72_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1606_172x72_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static uint8_t *u8x8_convert_tile_for_ssd1606(uint8_t *t)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t r;
|
||||
static uint8_t buf[16];
|
||||
uint8_t *pbuf = buf;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
r = u8x8_upscale_byte(~(*t++));
|
||||
*pbuf++ = (r>>8) & 255;
|
||||
*pbuf++ = r & 255;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void u8x8_d_ssd1606_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
|
||||
static void u8x8_d_ssd1606_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c, page;
|
||||
uint8_t *ptr;
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
page = u8x8->display_info->tile_height;
|
||||
page --;
|
||||
page -= (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
page *= 2;
|
||||
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x00f ); /* scan start */
|
||||
u8x8_cad_SendArg(u8x8, 0);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x011 ); /* cursor increment mode */
|
||||
u8x8_cad_SendArg(u8x8, 3);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x045 ); /* window start column */
|
||||
u8x8_cad_SendArg(u8x8, 0);
|
||||
u8x8_cad_SendArg(u8x8, 179); /* end of display */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x044 ); /* window end page */
|
||||
u8x8_cad_SendArg(u8x8, page);
|
||||
u8x8_cad_SendArg(u8x8, page+1);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x04f ); /* window column */
|
||||
u8x8_cad_SendArg(u8x8, x);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x04e ); /* window row */
|
||||
u8x8_cad_SendArg(u8x8, page);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x024 );
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 16, u8x8_convert_tile_for_ssd1606(ptr));
|
||||
ptr += 8;
|
||||
x += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t u8x8_d_ssd1606_172x72_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1606_172x72_display_info);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_gde021a1_init_seq);
|
||||
|
||||
/* special code for the SSD1606... */
|
||||
/* ensure that the initial buffer is clear and all eInk is set to white */
|
||||
/* this is done here, because the LUT will be of that kind, that it uses the previous color */
|
||||
/* make everything black */
|
||||
u8x8_FillDisplay(u8x8);
|
||||
/* write content to the display */
|
||||
u8x8_RefreshDisplay(u8x8);
|
||||
/* now make everything clear */
|
||||
u8x8_FillDisplay(u8x8);
|
||||
/* write content to the display */
|
||||
u8x8_RefreshDisplay(u8x8);
|
||||
/* now make everything clear */
|
||||
u8x8_ClearDisplay(u8x8);
|
||||
/* write content to the display */
|
||||
u8x8_RefreshDisplay(u8x8);
|
||||
|
||||
u8x8_ClearDisplay(u8x8);
|
||||
/* write content to the display */
|
||||
u8x8_RefreshDisplay(u8x8);
|
||||
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
/*
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_powersave1_seq);
|
||||
*/
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
/*
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
*/
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
/*
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
*/
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_d_ssd1606_draw_tile(u8x8, arg_int, arg_ptr);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_REFRESH:
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_to_display_seq);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1606_172x72_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 120,
|
||||
/* pre_chip_disable_wait_ns = */ 60,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100,
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1606: */
|
||||
/* sck_pulse_width_ns = */ 100, /* SSD1606: 100ns */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150,
|
||||
/* tile_width = */ 22, /* 22*8 = 176 */
|
||||
/* tile_hight = */ 9, /* 9*8 = 72 */
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 172,
|
||||
/* pixel_height = */ 72
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_ssd1606_172x72(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1606_172x72_display_info);
|
||||
return 1;
|
||||
}
|
||||
return u8x8_d_ssd1606_172x72_generic(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,507 @@
|
||||
/*
|
||||
|
||||
u8x8_d_ssd1607_200x200.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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.
|
||||
|
||||
SSD1607: 200x300x1
|
||||
|
||||
command
|
||||
0x22: assign actions
|
||||
0x20: execute actions
|
||||
|
||||
action for command 0x022 are (more or less guessed)
|
||||
bit 7: Enable Clock
|
||||
bit 6: Enable Charge Pump
|
||||
bit 5: Load Temparture Value (???)
|
||||
bit 4: Load LUT (???)
|
||||
bit 3: Initial Display (???)
|
||||
bit 2: Pattern Display --> Requires about 945ms with the LUT from below
|
||||
bit 1: Disable Charge Pump
|
||||
bit 0: Disable Clock
|
||||
|
||||
Disable Charge Pump and Clock require about 267ms
|
||||
Enable Charge Pump and Clock require about 10ms
|
||||
|
||||
Notes:
|
||||
- Introduced a refresh display message, which copies RAM to display
|
||||
- Charge pump and clock are only enabled for the transfer RAM to display
|
||||
- U8x8 will not really work because of the two buffers in the SSD1606, however U8g2 should be ok.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
/*=================================================*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_ssd1607_200x200_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* values from SSD1606 */
|
||||
/* post_chip_enable_wait_ns = */ 120,
|
||||
/* pre_chip_disable_wait_ns = */ 60,
|
||||
/* reset_pulse_width_ms = */ 100,
|
||||
/* post_reset_wait_ms = */ 100,
|
||||
/* sda_setup_time_ns = */ 50, /* SSD1606: */
|
||||
/* sck_pulse_width_ns = */ 100, /* SSD1606: 100ns */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 2, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40,
|
||||
/* write_pulse_width_ns = */ 150,
|
||||
/* tile_width = */ 25, /* 25*8 = 200 */
|
||||
/* tile_hight = */ 25,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 200,
|
||||
/* pixel_height = */ 200
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1607_200x200_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x22, 0xc0), /* enable clock and charge pump */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(200), /* according to my measures it may take up to 150ms */
|
||||
U8X8_DLY(100), /* but it might take longer */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1607_200x200_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
/* disable clock and charge pump only, deep sleep is not entered, because we will loose RAM content */
|
||||
U8X8_CA(0x22, 0x02), /* only disable charge pump, HW reset seems to be required if the clock is disabled */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(20),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1607_200x200_exec_1000dly_seq[] = {
|
||||
// assumes, that the start transfer has happend
|
||||
U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static void u8x8_d_ssd1607_200x200_first_init(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8_ClearDisplay(u8x8);
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x032); // program update sequence
|
||||
u8x8_cad_SendMultipleArg(u8x8, 8, 0x055); // all black
|
||||
u8x8_cad_SendMultipleArg(u8x8, 12, 0x0aa); // all white
|
||||
u8x8_cad_SendMultipleArg(u8x8, 10, 0x022); // 830ms
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_exec_1000dly_seq);
|
||||
|
||||
}
|
||||
|
||||
static uint8_t *u8x8_convert_tile_for_ssd1607(uint8_t *t)
|
||||
{
|
||||
uint8_t i;
|
||||
static uint8_t buf[8];
|
||||
uint8_t *pbuf = buf;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
*pbuf++ = ~(*t++);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void u8x8_d_ssd1607_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
|
||||
static void u8x8_d_ssd1607_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint16_t x;
|
||||
uint8_t c, page;
|
||||
uint8_t *ptr;
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
page = u8x8->display_info->tile_height;
|
||||
page --;
|
||||
page -= (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x045 ); /* window start column */
|
||||
u8x8_cad_SendArg(u8x8, 0);
|
||||
u8x8_cad_SendArg(u8x8, 0);
|
||||
u8x8_cad_SendArg(u8x8, 199); /* end of display */
|
||||
u8x8_cad_SendArg(u8x8, 0);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x044 ); /* window end page */
|
||||
u8x8_cad_SendArg(u8x8, page);
|
||||
u8x8_cad_SendArg(u8x8, page);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x04f ); /* window column */
|
||||
u8x8_cad_SendArg(u8x8, x&255);
|
||||
u8x8_cad_SendArg(u8x8, x>>8);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x04e ); /* window row */
|
||||
u8x8_cad_SendArg(u8x8, page);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x024 );
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 8, u8x8_convert_tile_for_ssd1607(ptr));
|
||||
ptr += 8;
|
||||
x += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=================================================*/
|
||||
|
||||
|
||||
#define L(a,b,c,d) (((a)<<6)|((b)<<4)|((c)<<2)|(d))
|
||||
|
||||
|
||||
/* https://github.com/embeddedadventures/SSD1607/blob/master/SSD1607.cpp */
|
||||
static const uint8_t u8x8_d_ssd1607_200x200_init_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
//U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: Disable */
|
||||
U8X8_C(0x01),
|
||||
U8X8_A(199),U8X8_A(0),U8X8_A(0),
|
||||
|
||||
|
||||
U8X8_CA(0x03, 0x00), /* Gate Driving voltage: 15V (lowest value)*/
|
||||
U8X8_CA(0x04, 0x0a), /* Source Driving voltage: 15V (mid value and POR)*/
|
||||
|
||||
U8X8_CA(0x0f, 0x00), /* scan start ? */
|
||||
|
||||
U8X8_CA(0xf0, 0x1f), /* set booster feedback to internal */
|
||||
|
||||
U8X8_CA(0x2c, 0xa8), /* write vcom value*/
|
||||
U8X8_CA(0x3a, 0x1a), /* dummy lines */
|
||||
U8X8_CA(0x3b, 0x08), /* gate time */
|
||||
U8X8_CA(0x3c, 0x33), /* select boarder waveform */
|
||||
|
||||
U8X8_CA(0x11, 0x03), /* cursor increment mode */
|
||||
U8X8_CAA(0x44, 0, 24), /* RAM x start & end, each byte has 8 pixel, 25*4=200 */
|
||||
U8X8_CAAAA(0x45, 0, 0, 299&255, 299>>8), /* RAM y start & end, 0..299 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_ssd1607_to_display_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x32), /* write LUT register*/
|
||||
|
||||
|
||||
/* according to the command table, the lut has 240 bits (=30 bytes * 8 bits) */
|
||||
|
||||
/* Waveform part of the LUT (20 bytes) */
|
||||
/* bit 7/6: 1 - 1 transition */
|
||||
/* bit 5/4: 1 - 0 transition */
|
||||
/* bit 3/2: 0 - 1 transition */
|
||||
/* bit 1/0: 0 - 0 transition */
|
||||
/* 00 – VSS */
|
||||
/* 01 – VSH */
|
||||
/* 10 – VSL */
|
||||
/* 11 – NA */
|
||||
|
||||
/* original values */
|
||||
/*
|
||||
U8X8_A(0x02),
|
||||
U8X8_A(0x02),
|
||||
U8X8_A(0x01),
|
||||
U8X8_A(0x11),
|
||||
U8X8_A(0x12),
|
||||
U8X8_A(0x12),
|
||||
U8X8_A(0x22),
|
||||
U8X8_A(0x22),
|
||||
U8X8_A(0x66),
|
||||
U8X8_A(0x69),
|
||||
U8X8_A(0x69),
|
||||
U8X8_A(0x59),
|
||||
U8X8_A(0x58),
|
||||
U8X8_A(0x99),
|
||||
U8X8_A(0x99),
|
||||
U8X8_A(0x88),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
*/
|
||||
|
||||
/* original values, L-macro */
|
||||
U8X8_A(L(0,0,0,2)), // 0x02
|
||||
U8X8_A(L(0,0,0,2)), // 0x02
|
||||
U8X8_A(L(0,0,0,1)), // 0x01
|
||||
U8X8_A(L(0,1,0,1)), // 0x11
|
||||
U8X8_A(L(0,1,0,2)), // 0x12
|
||||
U8X8_A(L(0,1,0,2)), // 0x12
|
||||
U8X8_A(L(0,2,0,2)), // 0x22
|
||||
U8X8_A(L(0,2,0,2)), // 0x22
|
||||
U8X8_A(L(1,2,1,2)), // 0x66
|
||||
U8X8_A(L(1,2,2,1)), // 0x69
|
||||
U8X8_A(L(1,2,2,1)), // 0x69
|
||||
U8X8_A(L(1,1,2,1)), // 0x59
|
||||
U8X8_A(L(1,1,2,0)), // 0x58
|
||||
U8X8_A(L(2,1,2,1)), // 0x99
|
||||
U8X8_A(L(2,1,2,1)), // 0x99
|
||||
U8X8_A(L(2,0,2,0)), // 0x88
|
||||
U8X8_A(L(0,0,0,0)), // 0x00
|
||||
U8X8_A(L(0,0,0,0)), // 0x00
|
||||
U8X8_A(L(0,0,0,0)), // 0x00
|
||||
U8X8_A(L(0,0,0,0)), // 0x00
|
||||
|
||||
|
||||
/* orginal values without 0-0 and 1-1 transition */
|
||||
/*
|
||||
U8X8_A(L(3,0,0,3)), // 0x02
|
||||
U8X8_A(L(3,0,0,3)), // 0x02
|
||||
U8X8_A(L(3,0,0,3)), // 0x01
|
||||
U8X8_A(L(3,1,0,3)), // 0x11
|
||||
U8X8_A(L(3,1,0,3)), // 0x12
|
||||
U8X8_A(L(3,1,0,3)), // 0x12
|
||||
U8X8_A(L(3,2,0,3)), // 0x22
|
||||
U8X8_A(L(3,2,0,3)), // 0x22
|
||||
U8X8_A(L(3,2,1,3)), // 0x66
|
||||
U8X8_A(L(3,2,2,3)), // 0x69
|
||||
U8X8_A(L(3,2,2,3)), // 0x69
|
||||
U8X8_A(L(3,1,2,3)), // 0x59
|
||||
U8X8_A(L(3,1,2,3)), // 0x58
|
||||
U8X8_A(L(3,1,2,3)), // 0x99
|
||||
U8X8_A(L(3,1,2,3)), // 0x99
|
||||
U8X8_A(L(3,0,2,3)), // 0x88
|
||||
U8X8_A(L(3,0,0,3)), // 0x00
|
||||
U8X8_A(L(3,0,0,3)), // 0x00
|
||||
U8X8_A(L(3,0,0,3)), // 0x00
|
||||
U8X8_A(L(3,0,0,3)), // 0x00
|
||||
*/
|
||||
|
||||
|
||||
/* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */
|
||||
U8X8_A(0xF8),
|
||||
U8X8_A(0xB4),
|
||||
U8X8_A(0x13),
|
||||
U8X8_A(0x51),
|
||||
U8X8_A(0x35),
|
||||
U8X8_A(0x51),
|
||||
U8X8_A(0x51),
|
||||
U8X8_A(0x19),
|
||||
U8X8_A(0x01),
|
||||
U8X8_A(0x00),
|
||||
|
||||
|
||||
U8X8_CA(0x22, 0x04), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
U8X8_DLY(250), /* the sequence above requires about 1200ms for the 200x200 display*/
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_ssd1607_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_init_seq);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
|
||||
u8x8_d_ssd1607_200x200_first_init(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_REFRESH:
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_to_display_seq);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*=================================================*/
|
||||
/* there is no improvement possible... so i consider the v2 version as obsolete */
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_ssd1607_v2_to_display_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
/*
|
||||
0xaa, 0x09, 0x09, 0x19, 0x19,
|
||||
0x11, 0x11, 0x11, 0x11, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x75, 0x77, 0x77, 0x77, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00
|
||||
measured 1240 ms with IL3830 196x128
|
||||
|
||||
|
||||
0x02, 0x02, 0x01, 0x11, 0x12,
|
||||
0x12, 0x12, 0x22, 0x22, 0x66,
|
||||
0x69, 0x59, 0x58, 0x99, 0x99,
|
||||
0x88, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0xf8, 0xb4, 0x13, 0x51, 0x35,
|
||||
0x51, 0x51, 0xe9, 0x04, 0x00
|
||||
|
||||
*/
|
||||
|
||||
U8X8_C(0x32), /* write LUT register*/
|
||||
|
||||
/* https://github.com/olikraus/u8g2/issues/347 */
|
||||
U8X8_A(0x02),
|
||||
U8X8_A(0x02),
|
||||
U8X8_A(0x01),
|
||||
U8X8_A(0x11),
|
||||
U8X8_A(0x12),
|
||||
U8X8_A(0x12),
|
||||
U8X8_A(0x22),
|
||||
U8X8_A(0x22),
|
||||
U8X8_A(0x66),
|
||||
U8X8_A(0x69),
|
||||
U8X8_A(0x69),
|
||||
U8X8_A(0x59),
|
||||
U8X8_A(0x58),
|
||||
U8X8_A(0x99),
|
||||
U8X8_A(0x99),
|
||||
|
||||
U8X8_A(0x88),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
U8X8_A(0x00),
|
||||
|
||||
/* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */
|
||||
U8X8_A(0xF8),
|
||||
U8X8_A(0xB4),
|
||||
U8X8_A(0x13),
|
||||
U8X8_A(0x51),
|
||||
U8X8_A(0x35),
|
||||
|
||||
U8X8_A(0x51),
|
||||
U8X8_A(0x51),
|
||||
U8X8_A(0xe9),
|
||||
U8X8_A(0x04),
|
||||
U8X8_A(0x00),
|
||||
|
||||
U8X8_CA(0x22, 0x04), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
|
||||
U8X8_C(0x20), /* execute sequence */
|
||||
|
||||
U8X8_DLY(250), /* delay for 1500ms. The current sequence takes 1300ms */
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
|
||||
U8X8_DLY(250),
|
||||
U8X8_DLY(250),
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_ssd1607_v2_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_init_seq);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
|
||||
u8x8_d_ssd1607_200x200_first_init(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_REFRESH:
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_v2_to_display_seq);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,668 @@
|
||||
/*
|
||||
|
||||
u8x8_d_st75256.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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.
|
||||
|
||||
0x030 ext 00
|
||||
0x031 ext 01
|
||||
0x038 ext 10
|
||||
0x039 ext 11
|
||||
|
||||
cad 011
|
||||
|
||||
|
||||
code examples:
|
||||
http://www.it610.com/article/2601023.htm
|
||||
|
||||
normal mode:
|
||||
0x00c bit format
|
||||
U8X8_CA( 0xbc, 0x00 ), data scan dir
|
||||
U8X8_A( 0xa6 ),
|
||||
y: 0 offset
|
||||
|
||||
flip mode:
|
||||
0x008 bit format
|
||||
U8X8_CA( 0xbc, 0x03 ), data scan dir
|
||||
U8X8_A( 0xa6 ),
|
||||
y: 5 offset
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
/* not a real power down for the st75256... just a display off */
|
||||
static const uint8_t u8x8_d_st75256_256x128_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x94 ), /* sleep out */
|
||||
U8X8_DLY(10),
|
||||
U8X8_C( 0xaf ), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st75256_256x128_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0xae ), /* display off */
|
||||
U8X8_C( 0x95 ), /* sleep in */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st75256_jlx256128_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0xbc, 0x00 ), /* data scan dir */
|
||||
U8X8_A( 0xa6 ), /* ??? */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x00c ), /* data format LSB top */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st75256_jlx256128_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0xbc, 0x03 ), /* data scan dir */
|
||||
U8X8_A( 0xa6 ), /* ??? */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x008 ), /* data format MSB top */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_d_st75256_256x128_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st75256_256x128_display_info);
|
||||
break;
|
||||
*/
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave1_seq);
|
||||
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x030 );
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 ); /* there are 9 bit for the volume control */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int & 0x1f)<<1 ); /* lower 6 bit */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int>>5)); /* upper 3 bit */
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x030 ); /* select command set */
|
||||
u8x8_cad_SendCmd(u8x8, 0x075 ); /* row */
|
||||
u8x8_cad_SendArg(u8x8, u8x8->x_offset + (((u8x8_tile_t *)arg_ptr)->y_pos)); /* x offset is used as y offset */
|
||||
u8x8_cad_SendArg(u8x8, 0x04f);
|
||||
//u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
u8x8_cad_SendCmd(u8x8, 0x015 ); /* col */
|
||||
u8x8_cad_SendArg(u8x8, x);
|
||||
u8x8_cad_SendArg(u8x8, 255);
|
||||
u8x8_cad_SendCmd(u8x8, 0x05c );
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
/* SendData can not handle more than 255 bytes, treat c > 31 correctly */
|
||||
if ( c > 31 )
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, 248, ptr); /* 31*8=248 */
|
||||
ptr+=248;
|
||||
c -= 31;
|
||||
}
|
||||
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr);
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=============================================*/
|
||||
/* JLX256128 */
|
||||
|
||||
static const u8x8_display_info_t u8x8_st75256_256x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 5,
|
||||
/* post_reset_wait_ms = */ 5, /**/
|
||||
/* sda_setup_time_ns = */ 20, /* */
|
||||
/* sck_pulse_width_ns = */ 40, /* */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4, /* 400KHz */
|
||||
/* data_setup_time_ns = */ 15,
|
||||
/* write_pulse_width_ns = */ 70,
|
||||
/* tile_width = */ 32,
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0, /* must be 0, because this is checked also for normal mode */
|
||||
/* flipmode_x_offset = */ 5, /* used as y offset */
|
||||
/* pixel_width = */ 256,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st75256_256x128_init_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_DLY(20),
|
||||
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x094 ), /* sleep out */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x0ae ), /* display off */
|
||||
|
||||
U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_CA( 0x0d7, 0x09f ), /* disable auto read */
|
||||
|
||||
//U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_C( 0x032 ), /* analog circuit set */
|
||||
U8X8_A( 0x000 ), /* code example: OSC Frequency adjustment */
|
||||
U8X8_A( 0x001 ), /* Frequency on booster capacitors 1 = 6KHz? */
|
||||
U8X8_A( 0x000 ), /* Bias: 1: 1/13, 2: 1/12, 3: 1/11, 4:1/10, 5:1/9 */
|
||||
|
||||
//U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_C( 0x020 ), /* gray levels */
|
||||
U8X8_A( 0x01 ),
|
||||
U8X8_A( 0x03 ),
|
||||
U8X8_A( 0x05 ),
|
||||
U8X8_A( 0x07 ),
|
||||
U8X8_A( 0x09),
|
||||
U8X8_A( 0x0b ),
|
||||
U8X8_A( 0x0d ),
|
||||
U8X8_A( 0x10 ),
|
||||
U8X8_A( 0x11 ),
|
||||
U8X8_A( 0x13 ),
|
||||
U8X8_A( 0x15 ),
|
||||
U8X8_A( 0x17 ),
|
||||
U8X8_A( 0x19 ),
|
||||
U8X8_A( 0x1b ),
|
||||
U8X8_A( 0x1d ),
|
||||
U8X8_A( 0x1f ),
|
||||
|
||||
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CAA(0x75, 0, 0x4f), /* row range */
|
||||
U8X8_CAA(0x15, 0, 255), /* col range */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0xbc, 0x00 ), /* data scan dir */
|
||||
U8X8_A( 0xa6 ), /* ??? */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x00c ), /* data format LSB top */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0xca ), /* display control, 3 args follow */
|
||||
U8X8_A( 0x00 ), /* 0x00: no clock division, 0x04: devide clock */
|
||||
U8X8_A( 0x7f ), /* 1/160 duty value from the DS example code */
|
||||
U8X8_A( 0x20 ), /* nline off */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0x0f0, 0x010 ), /* monochrome mode = 0x010*/
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CAA( 0x81, 0x36, 0x05 ), /* Volume control */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0x020, 0x00b ), /* Power control: Regulator, follower & booster on */
|
||||
U8X8_DLY(100),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_st75256_jlx256128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( u8x8_d_st75256_256x128_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
//u8x8_SetI2CAddress(u8x8, 0x078); /* lowest I2C adr of the ST75256 */
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st75256_256x128_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_init_seq);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
|
||||
{
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx256128_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx256128_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
/* JLX25664 */
|
||||
|
||||
static const u8x8_display_info_t u8x8_st75256_256x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 5,
|
||||
/* post_reset_wait_ms = */ 5, /**/
|
||||
/* sda_setup_time_ns = */ 20, /* */
|
||||
/* sck_pulse_width_ns = */ 40, /* */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4, /* 400KHz */
|
||||
/* data_setup_time_ns = */ 15,
|
||||
/* write_pulse_width_ns = */ 70,
|
||||
/* tile_width = */ 32,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0, /* must be 0, because this is checked also for normal mode */
|
||||
/* flipmode_x_offset = */ 13, /* used as y offset */
|
||||
/* pixel_width = */ 256,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st75256_256x64_init_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_DLY(20),
|
||||
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x094 ), /* sleep out */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x0ae ), /* display off */
|
||||
|
||||
U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_CA( 0x0d7, 0x09f ), /* disable auto read */
|
||||
|
||||
//U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_C( 0x032 ), /* analog circuit set */
|
||||
U8X8_A( 0x000 ), /* code example: OSC Frequency adjustment */
|
||||
U8X8_A( 0x001 ), /* Frequency on booster capacitors 1 = 6KHz? */
|
||||
U8X8_A( 0x005 ), /* Bias: 1: 1/13, 2: 1/12, 3: 1/11, 4:1/10, 5:1/9 */
|
||||
|
||||
//U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_C( 0x020 ), /* gray levels */
|
||||
U8X8_A( 0x01 ),
|
||||
U8X8_A( 0x03 ),
|
||||
U8X8_A( 0x05 ),
|
||||
U8X8_A( 0x07 ),
|
||||
U8X8_A( 0x09),
|
||||
U8X8_A( 0x0b ),
|
||||
U8X8_A( 0x0d ),
|
||||
U8X8_A( 0x10 ),
|
||||
U8X8_A( 0x11 ),
|
||||
U8X8_A( 0x13 ),
|
||||
U8X8_A( 0x15 ),
|
||||
U8X8_A( 0x17 ),
|
||||
U8X8_A( 0x19 ),
|
||||
U8X8_A( 0x1b ),
|
||||
U8X8_A( 0x1d ),
|
||||
U8X8_A( 0x1f ),
|
||||
|
||||
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CAA(0x75, 0, 0x1f), /* row range */
|
||||
U8X8_CAA(0x15, 0, 255), /* col range */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0xbc, 0x00 ), /* data scan dir */
|
||||
U8X8_A( 0xa6 ), /* ??? */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x00c ), /* data format LSB top */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0xca ), /* display control, 3 args follow */
|
||||
U8X8_A( 0x00 ), /* 0x00: no clock division, 0x04: devide clock */
|
||||
U8X8_A( 0x3f ), /* 64 duty value from the DS example code */
|
||||
U8X8_A( 0x20 ), /* nline off */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0x0f0, 0x010 ), /* monochrome mode = 0x010*/
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CAA( 0x81, 012, 0x02 ), /* Volume control */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0x020, 0x00b ), /* Power control: Regulator, follower & booster on */
|
||||
U8X8_DLY(100),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_st75256_jlx25664(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( u8x8_d_st75256_256x128_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
//u8x8_SetI2CAddress(u8x8, 0x078); /* lowest I2C adr of the ST75256 */
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st75256_256x64_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x64_init_seq);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
|
||||
{
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx256128_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx256128_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
/* JLX172104 LCD */
|
||||
|
||||
static const u8x8_display_info_t u8x8_st75256_172x104_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 5,
|
||||
/* post_reset_wait_ms = */ 5, /**/
|
||||
/* sda_setup_time_ns = */ 20, /* */
|
||||
/* sck_pulse_width_ns = */ 40, /* */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4, /* 400KHz */
|
||||
/* data_setup_time_ns = */ 15,
|
||||
/* write_pulse_width_ns = */ 70,
|
||||
/* tile_width = */ 22, /* 22=176 */
|
||||
/* tile_hight = */ 13,
|
||||
/* default_x_offset = */ 84, /* */
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 172,
|
||||
/* pixel_height = */ 104
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st75256_jlx172104_init_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_DLY(20),
|
||||
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x094 ), /* sleep out */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x0ae ), /* display off */
|
||||
|
||||
U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_CA( 0x0d7, 0x09f ), /* disable auto read */
|
||||
|
||||
//U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_C( 0x032 ), /* analog circuit set */
|
||||
U8X8_A( 0x000 ), /* code example: OSC Frequency adjustment */
|
||||
U8X8_A( 0x001 ), /* Frequency on booster capacitors 1 = 6KHz? */
|
||||
U8X8_A( 0x003 ), /* Bias: 1: 1/13, 2: 1/12, 3: 1/11, 4:1/10, 5:1/9 */
|
||||
|
||||
//U8X8_C( 0x031 ), /* select 01 commands */
|
||||
U8X8_C( 0x020 ), /* gray levels */
|
||||
U8X8_A( 0x01 ),
|
||||
U8X8_A( 0x03 ),
|
||||
U8X8_A( 0x05 ),
|
||||
U8X8_A( 0x07 ),
|
||||
U8X8_A( 0x09),
|
||||
U8X8_A( 0x0b ),
|
||||
U8X8_A( 0x0d ),
|
||||
U8X8_A( 0x10 ),
|
||||
U8X8_A( 0x11 ),
|
||||
U8X8_A( 0x13 ),
|
||||
U8X8_A( 0x15 ),
|
||||
U8X8_A( 0x17 ),
|
||||
U8X8_A( 0x19 ),
|
||||
U8X8_A( 0x1b ),
|
||||
U8X8_A( 0x1d ),
|
||||
U8X8_A( 0x1f ),
|
||||
|
||||
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CAA(0x75, 0, 0x4f), /* row range */
|
||||
U8X8_CAA(0x15, 0, 255), /* col range */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0xbc, 0x02 ), /* data scan dir */
|
||||
U8X8_A( 0xa6 ), /* ??? */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x00c ), /* data format LSB top */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0xca ), /* display control, 3 args follow */
|
||||
U8X8_A( 0x00 ), /* 0x00: no clock division, 0x04: devide clock */
|
||||
U8X8_A( 0x9f ), /* 1/160 duty value from the DS example code */
|
||||
U8X8_A( 0x20 ), /* nline off */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0x0f0, 0x010 ), /* monochrome mode = 0x010*/
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CAA( 0x81, 0x08, 0x04 ), /* Volume control */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0x020, 0x00b ), /* Power control: Regulator, follower & booster on */
|
||||
U8X8_DLY(100),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st75256_jlx172104_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0xbc, 0x02 ), /* data scan dir */
|
||||
U8X8_A( 0xa6 ), /* ??? */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x00c ), /* data format LSB top */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st75256_jlx172104_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_CA( 0xbc, 0x01 ), /* data scan dir */
|
||||
U8X8_A( 0xa6 ), /* ??? */
|
||||
|
||||
//U8X8_C( 0x030 ), /* select 00 commands */
|
||||
U8X8_C( 0x008 ), /* data format MSB top */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_st75256_jlx172104(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x030 ); /* select command set */
|
||||
u8x8_cad_SendCmd(u8x8, 0x075 ); /* row */
|
||||
if ( u8x8->x_offset == 0 ) /* 0 means flip mode 1, then adjust y value */
|
||||
u8x8_cad_SendArg(u8x8, 8+(((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
else
|
||||
u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
u8x8_cad_SendArg(u8x8, 0x04f);
|
||||
//u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
u8x8_cad_SendCmd(u8x8, 0x015 ); /* col */
|
||||
u8x8_cad_SendArg(u8x8, x+u8x8->x_offset);
|
||||
u8x8_cad_SendArg(u8x8, 255);
|
||||
u8x8_cad_SendCmd(u8x8, 0x05c );
|
||||
|
||||
|
||||
/* this procedure assumes, that the overall width is 172 */
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
c *= 8;
|
||||
|
||||
if ( c + x > 172u )
|
||||
{
|
||||
c = 172u;
|
||||
c -= x;
|
||||
}
|
||||
|
||||
u8x8_cad_SendData(u8x8, c, ptr);
|
||||
x += c;
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
return 1;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
//u8x8_SetI2CAddress(u8x8, 0x078); /* lowest I2C adr of the ST75256 */
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st75256_172x104_display_info);
|
||||
return 1;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx172104_init_seq);
|
||||
return 1;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave1_seq);
|
||||
|
||||
return 1;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx172104_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx172104_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
return 1;
|
||||
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x030 );
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 ); /* there are 9 bit for the volume control */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int & 0x1f)<<1 ); /* lower 6 bit */
|
||||
u8x8_cad_SendArg(u8x8, (arg_int>>5)); /* upper 3 bit */
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,960 @@
|
||||
/*
|
||||
|
||||
u8x8_d_st7565.c
|
||||
also includes support for nt7534
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st7565_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a4), /* all pixel off, issue 142 */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7565_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7565_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7565_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7565_zflip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7565_zflip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7565_128x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* st7565 datasheet, table 26, tcsh */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* st7565 datasheet, table 26, tcss */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* st7565 datasheet, table 26, tsds */
|
||||
/* sck_pulse_width_ns = */ 120, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* st7565 datasheet, table 24, tds8 */
|
||||
/* write_pulse_width_ns = */ 80, /* st7565 datasheet, table 24, tcclw */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 4,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
/*
|
||||
The following if condition checks the hardware limits of the st7565
|
||||
controller: It is not allowed to write beyond the display limits.
|
||||
This is in fact an issue within flip mode.
|
||||
*/
|
||||
if ( c + x > 132u )
|
||||
{
|
||||
c = 132u;
|
||||
c -= x;
|
||||
}
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
/* handled in the calling procedure
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_powersave1_seq);
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7565 has range from 0 to 63 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* DOGM128 */
|
||||
|
||||
static const uint8_t u8x8_d_st7565_dogm128_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
// U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a2), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on (regulator, booster and follower) */
|
||||
U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x */
|
||||
U8X8_C(0x027), /* set V0 voltage resistor ratio to max */
|
||||
U8X8_CA(0x081, 0x018), /* set contrast, contrast value, EA default: 0x016 */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_ea_dogm128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_dogm128_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* Displaytech 64128n */
|
||||
|
||||
static const uint8_t u8x8_d_st7565_64128n_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
#ifdef NOT_WORKING
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
// U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a2), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on */
|
||||
//U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x */
|
||||
//U8X8_C(0x027), /* set V0 voltage resistor ratio to max */
|
||||
|
||||
U8X8_C(0x010), /* Set V0 voltage resistor ratio. Setting for controlling brightness of Displaytech 64128N */
|
||||
|
||||
|
||||
U8X8_CA(0x081, 0x01e), /* set contrast, contrast value */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
#else
|
||||
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0A2), /* 0x0a2: LCD bias 1/9 (according to Displaytech 64128N datasheet) */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
//U8X8_C(0x0A0), /* Normal ADC Select (according to Displaytech 64128N datasheet) */
|
||||
//U8X8_C(0x0c8), /* common output mode: set scan direction normal operation/SHL Select, 0x0c0 --> SHL = 0, normal, 0x0c8 --> SHL = 1 */
|
||||
|
||||
U8X8_C(0x040), /* Display start line for Displaytech 64128N */
|
||||
U8X8_C(0x028 | 0x04), /* power control: turn on voltage converter */
|
||||
U8X8_C(0x028 | 0x06), /* power control: turn on voltage regulator */
|
||||
U8X8_C(0x028 | 0x07), /* power control: turn on voltage follower */
|
||||
U8X8_C(0x010), /* Set V0 voltage resistor ratio. Setting for controlling brightness of Displaytech 64128N */
|
||||
/* 19 Jul 17: Not sure if this is true, cmd 0x1? is used to set the column */
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x081), /* set contrast */
|
||||
U8X8_C(0x01e), /* Contrast value. Setting for controlling brightness of Displaytech 64128N */
|
||||
//U8X8_C(0x0af), /* display on */
|
||||
//U8X8_C(0x0a5), /* display all points, ST7565 */
|
||||
//U8X8_C(0x0a4), /* normal display */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7565_64128n_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* st7565 datasheet, table 26, tcsh */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* st7565 datasheet, table 26, tcss */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* st7565 datasheet, table 26, tsds */
|
||||
/* sck_pulse_width_ns = */ 120, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* st7565 datasheet, table 24, tds8 */
|
||||
/* write_pulse_width_ns = */ 80, /* st7565 datasheet, table 24, tcclw */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 4,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_64128n(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_64128n_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_64128n_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* ZOLEN 128x64 */
|
||||
|
||||
static const uint8_t u8x8_d_st7565_zolen_128x64_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c8), /* common output mode */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
// U8X8_C(0x0c0), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a2), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on (regulator, booster and follower) */
|
||||
U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x */
|
||||
U8X8_C(0x027), /* set V0 voltage resistor ratio to max */
|
||||
U8X8_CA(0x081, 0x007), /* set contrast, contrast value, EA default: 0x016 */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_zolen_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_zolen_128x64_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_zflip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_zflip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* NHD-C12832 */
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7565_128x32_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* st7565 datasheet, table 26, tcsh */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* st7565 datasheet, table 26, tcss */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* st7565 datasheet, table 26, tsds */
|
||||
/* sck_pulse_width_ns = */ 120, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* st7565 datasheet, table 24, tds8 */
|
||||
/* write_pulse_width_ns = */ 80, /* st7565 datasheet, table 24, tcclw */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 4,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st7565_nhd_c12832_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
//U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a2), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on */
|
||||
U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x */
|
||||
U8X8_C(0x023), /* set V0 voltage resistor ratio to large*/
|
||||
U8X8_CA(0x081, 0x00a), /* set contrast, contrast value NHD C12832 */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_nhd_c12832(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_128x32_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_nhd_c12832_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* NHD-C12864 */
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7565_nhd_c12864_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* st7565 datasheet, table 26, tcsh */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* st7565 datasheet, table 26, tcss */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* st7565 datasheet, table 26, tsds */
|
||||
/* sck_pulse_width_ns = */ 120, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* st7565 datasheet, table 24, tds8 */
|
||||
/* write_pulse_width_ns = */ 80, /* st7565 datasheet, table 24, tcclw */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 4,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st7565_nhd_c12864_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
//U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a2), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on */
|
||||
U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x */
|
||||
U8X8_C(0x023), /* set V0 voltage resistor ratio to large*/
|
||||
U8X8_CA(0x081, 180), /* set contrast, contrast value NHD C12864, see issue 186, increased contrast to 180 (issue 219) */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_nhd_c12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_nhd_c12864_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_nhd_c12864_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* LM6059 (Adafruit)... probably this is a ST7567 display */
|
||||
|
||||
static const uint8_t u8x8_d_st7565_lm6059_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x060), /* set display start line to ... */
|
||||
|
||||
U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
U8X8_C(0x0c8), /* common output mode */
|
||||
//U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
// U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a3), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on (regulator, booster and follower) */
|
||||
U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x (ST7567 feature) */
|
||||
U8X8_C(0x027), /* set V0 voltage resistor ratio to max */
|
||||
U8X8_CA(0x081, 0x018), /* set contrast, contrast value, EA default: 0x016 */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7565_lm6059_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* st7565 datasheet, table 26, tcsh */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* st7565 datasheet, table 26, tcss */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* st7565 datasheet, table 26, tsds */
|
||||
/* sck_pulse_width_ns = */ 120, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* st7565 datasheet, table 24, tds8 */
|
||||
/* write_pulse_width_ns = */ 80, /* st7565 datasheet, table 24, tcclw */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 1, /* not sure... */
|
||||
/* flipmode_x_offset = */ 3,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_lm6059(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_lm6059_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_lm6059_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* ERC12864-1 (buydisplay.com) */
|
||||
|
||||
static const uint8_t u8x8_d_st7565_erc12864_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to ... */
|
||||
|
||||
U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
U8X8_C(0x0c8), /* common output mode */
|
||||
//U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
// U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
// U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a3), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on (regulator, booster and follower) */
|
||||
U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x (ST7567 feature)*/
|
||||
U8X8_C(0x027), /* set V0 voltage resistor ratio to max */
|
||||
U8X8_CA(0x081, 0x018), /* set contrast, contrast value, EA default: 0x016 */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7565_erc12864_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* st7565 datasheet, table 26, tcsh */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* st7565 datasheet, table 26, tcss */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* st7565 datasheet, table 26, tsds */
|
||||
/* sck_pulse_width_ns = */ 120, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* st7565 datasheet, table 24, tds8 */
|
||||
/* write_pulse_width_ns = */ 80, /* st7565 datasheet, table 24, tcclw */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 4,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_erc12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_erc12864_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_erc12864_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* NT7534, TG12864R */
|
||||
/* The NT7534 has an extended command set for the ST7565, however this is not used. */
|
||||
/* The TG12864R display is also shifted in lines, like the LM6059/Adafruit display */
|
||||
/* However contrast seems to be different */
|
||||
|
||||
static const uint8_t u8x8_d_nt7534_tg12864r_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x060), /* set display start line to ... */
|
||||
|
||||
U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
U8X8_C(0x0c8), /* common output mode */
|
||||
// Flipmode
|
||||
//U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c0), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a3), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on (regulator, booster and follower) */
|
||||
//U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x (ST7567 feature)*/
|
||||
U8X8_C(0x027), /* set V0 voltage resistor ratio to max */
|
||||
U8X8_CA(0x081, 0x009), /* set contrast, contrast value, EA default: 0x016 */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_nt7534_tg12864r(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
/* reuse the LM6059 data structure... this display seems to have similar shifts and offsets */
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_lm6059_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
|
||||
//u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_lm6059_init_seq);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_nt7534_tg12864r_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* EA DOGM132 */
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7565_dogm132_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* st7565 datasheet, table 26, tcsh */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* st7565 datasheet, table 26, tcss */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* st7565 datasheet, table 26, tsds */
|
||||
/* sck_pulse_width_ns = */ 120, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* st7565 datasheet, table 24, tds8 */
|
||||
/* write_pulse_width_ns = */ 80, /* st7565 datasheet, table 24, tcclw */
|
||||
/* tile_width = */ 17, /* width of 16*8=136 pixel */
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 132,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st7565_dogm132_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
//U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a2), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on */
|
||||
U8X8_CA(0x0f8, 0x000), /* set booster ratio to 4x */
|
||||
U8X8_C(0x023), /* set V0 voltage resistor ratio to large*/
|
||||
U8X8_CA(0x081, 0x01f), /* set contrast, contrast value EA DOGM132 */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7565_ea_dogm132(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_st7565_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7565_dogm132_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_dogm132_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
|
||||
u8x8_d_st7567.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st7567_132x64_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a4), /* all pixel off, issue 142 */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7567_132x64_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7567_132x64_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7567_132x64_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/*=====================================================*/
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7567_132x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* */
|
||||
/* sck_pulse_width_ns = */ 120, /* */
|
||||
/* sck_clock_hz = */ 4000000UL, /* */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* */
|
||||
/* write_pulse_width_ns = */ 80, /* */
|
||||
/* tile_width = */ 17, /* width of 17*8=136 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 132,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7567_132x64_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
//U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a3), /* LCD bias 1/7 */
|
||||
/* power on sequence from paxinstruments */
|
||||
U8X8_C(0x028|4), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
U8X8_C(0x028|6), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
U8X8_C(0x028|7), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_C(0x026), /* v0 voltage resistor ratio */
|
||||
U8X8_CA(0x081, 0x027), /* set contrast, contrast value*/
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
/* pax instruments 132x64 display */
|
||||
uint8_t u8x8_d_st7567_pi_132x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_132x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
/*
|
||||
The following if condition checks the hardware limits of the st7567
|
||||
controller: It is not allowed to write beyond the display limits.
|
||||
This is in fact an issue within flip mode.
|
||||
*/
|
||||
if ( c + x > 132u )
|
||||
{
|
||||
c = 132u;
|
||||
c -= x;
|
||||
}
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*=====================================================*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7567_jlx12864_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150, /* */
|
||||
/* pre_chip_disable_wait_ns = */ 50, /* */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 1,
|
||||
/* sda_setup_time_ns = */ 50, /* */
|
||||
/* sck_pulse_width_ns = */ 120, /* */
|
||||
/* sck_clock_hz = */ 4000000UL, /* */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 40, /* */
|
||||
/* write_pulse_width_ns = */ 80, /* */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 4,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_st7567_jlx12864_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
//U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a3), /* LCD bias 1/7 */
|
||||
/* power on sequence from paxinstruments */
|
||||
U8X8_C(0x028|4), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
U8X8_C(0x028|6), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
U8X8_C(0x028|7), /* all power control circuits on */
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_C(0x023), /* v0 voltage resistor ratio */
|
||||
U8X8_CA(0x081, 42>>2), /* set contrast, contrast value*/
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
/* JLX12864 display */
|
||||
uint8_t u8x8_d_st7567_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_jlx12864_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_st7567_jlx12864_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
/*
|
||||
The following if condition checks the hardware limits of the st7567
|
||||
controller: It is not allowed to write beyond the display limits.
|
||||
This is in fact an issue within flip mode.
|
||||
*/
|
||||
if ( c + x > 132u )
|
||||
{
|
||||
c = 132u;
|
||||
c -= x;
|
||||
}
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
|
||||
u8x8_d_st7588.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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.
|
||||
|
||||
ST7588
|
||||
- has 4 different I2C addresses
|
||||
- I2C protocol is identical to SSD13xx
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
/* function set, bit 2: power down, bit 3: MY, bit 4: MX, bit 5: must be 1 */
|
||||
#define FS (0x020)
|
||||
|
||||
/* not a real power down for the ST7588... just a display off */
|
||||
static const uint8_t u8x8_d_st7588_128x64_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( FS | 0x00 ), /* select 00 commands */
|
||||
//U8X8_C( 0x08 ), /* display off */
|
||||
U8X8_C( 0x0c ), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7588_128x64_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( FS | 0x00 ), /* select 00 commands */
|
||||
U8X8_C( 0x08 ), /* display off */
|
||||
//U8X8_C( 0x0c ), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static uint8_t u8x8_d_st7588_128x64_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7588_128x64_display_info);
|
||||
break;
|
||||
*/
|
||||
/* handled by the calling function
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_128x64_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_128x64_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_128x64_powersave1_seq);
|
||||
|
||||
/* restore orientation */
|
||||
if ( u8x8->x_offset == 0 )
|
||||
u8x8_cad_SendCmd(u8x8, FS ); /* select 00 commands */
|
||||
else
|
||||
u8x8_cad_SendCmd(u8x8, FS ^ 0x018 ); /* select 00 commands */
|
||||
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, FS );
|
||||
u8x8_cad_SendArg(u8x8, 4 | (arg_int>>7) );
|
||||
u8x8_cad_SendCmd(u8x8, FS | 1);
|
||||
u8x8_cad_SendArg(u8x8, 0x080 | arg_int );
|
||||
|
||||
/* restore orientation */
|
||||
if ( u8x8->x_offset == 0 )
|
||||
u8x8_cad_SendCmd(u8x8, FS ); /* select 00 commands */
|
||||
else
|
||||
u8x8_cad_SendCmd(u8x8, FS ^ 0x018 ); /* select 00 commands */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
|
||||
x += u8x8->x_offset;
|
||||
|
||||
if ( u8x8->x_offset == 0 )
|
||||
u8x8_cad_SendCmd(u8x8, FS ); /* select 00 commands */
|
||||
else
|
||||
u8x8_cad_SendCmd(u8x8, FS ^ 0x018 ); /* select 00 commands */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x040 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0e0 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0f0 | (x>>4) );
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=============================================*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7588_128x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 150,
|
||||
/* pre_chip_disable_wait_ns = */ 30,
|
||||
/* reset_pulse_width_ms = */ 5,
|
||||
/* post_reset_wait_ms = */ 5, /**/
|
||||
/* sda_setup_time_ns = */ 60, /* */
|
||||
/* sck_pulse_width_ns = */ 60, /* */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4, /* 400KHz */
|
||||
/* data_setup_time_ns = */ 80,
|
||||
/* write_pulse_width_ns = */ 50,
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0, /* must be 0, because this is checked also for normal mode */
|
||||
/* flipmode_x_offset = */ 4,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st7588_128x64_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C( FS | 0x03 ), /* select 11 commands */
|
||||
U8X8_C( 0x03 ), /* software reset */
|
||||
|
||||
U8X8_C( FS | 0x00 ), /* select 00 commands */
|
||||
U8X8_C( 0x08 ), /* display off */
|
||||
//U8X8_C( 0x0c ), /* display on */
|
||||
|
||||
U8X8_C( FS | 0x01 ), /* select 01 commands */
|
||||
U8X8_C( 0x08 ), /* display confguration */
|
||||
U8X8_C( 0x12 ), /* bias 1/9 */
|
||||
U8X8_C( 0x8f ), /* Vop, lower 7 bits */
|
||||
|
||||
U8X8_C( FS | 0x00 ), /* select 00 commands */
|
||||
U8X8_C( 0x05), /* Bit 0 contains high/low range for Vop */
|
||||
|
||||
|
||||
U8X8_C( FS | 0x03 ), /* select 11 commands */
|
||||
U8X8_C( 0x0b), /* Frame Rate: 73 Hz */
|
||||
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st7588_jlx12864_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( FS ), /* normal mode */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7588_jlx12864_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C( FS ^ 0x018 ), /* normal mode */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_st7588_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
if ( u8x8_d_st7588_128x64_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
|
||||
return 1;
|
||||
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
|
||||
{
|
||||
u8x8_SetI2CAddress(u8x8, 0x07e); /* the JLX12864 has 0x07e as a default address for I2C */
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7588_128x64_display_info);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_INIT )
|
||||
{
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_128x64_init_seq);
|
||||
return 1;
|
||||
}
|
||||
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
|
||||
{
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_jlx12864_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_jlx12864_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
|
||||
u8x8_d_st7920.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, olikraus@gmail.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
The ST7920 controller does not support hardware graphics flip.
|
||||
Contrast adjustment is done by an external resistor --> no support for contrast adjustment
|
||||
|
||||
|
||||
*/
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_st7920_init_seq[] = {
|
||||
|
||||
U8X8_DLY(100),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(10),
|
||||
|
||||
U8X8_C(0x038), /* 8 Bit interface (DL=1), basic instruction set (RE=0) */
|
||||
U8X8_C(0x008), /* display on, cursor & blink off; 0x08: all off */
|
||||
U8X8_C(0x006), /* Entry mode: Cursor move to right ,DDRAM address counter (AC) plus 1, no shift */
|
||||
U8X8_C(0x002), /* disable scroll, enable CGRAM adress */
|
||||
U8X8_C(0x001), /* clear RAM, needs 1.6 ms */
|
||||
U8X8_DLY(4), /* delay 2ms */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7920_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x038), /* 8 Bit interface (DL=1), basic instruction set (RE=0) */
|
||||
U8X8_C(0x00c), /* display on, cursor & blink off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_st7920_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x038), /* 8 Bit interface (DL=1), basic instruction set (RE=0) */
|
||||
U8X8_C(0x008), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_st7920_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c, i;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
|
||||
/*
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7920_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7920_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_st7920_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
y*=8;
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x /= 2; /* not sure whether this is a clever idea, problem is, the ST7920 can address only every second tile */
|
||||
|
||||
if ( y >= 32 ) /* this is the adjustment for 128x64 displays */
|
||||
{
|
||||
y-=32;
|
||||
x+=8;
|
||||
}
|
||||
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
|
||||
/*
|
||||
Tile structure is reused here for the ST7920, however u8x8 is not supported
|
||||
tile_ptr points to data which has cnt*8 bytes (same as SSD1306 tiles)
|
||||
Buffer is expected to have 8 lines of code fitting to the ST7920 internal memory
|
||||
"cnt" includes the number of horizontal bytes. width is equal to cnt*8
|
||||
Also important: Width must be a multiple of 16 (ST7920 requirement), so cnt must be even.
|
||||
|
||||
TODO: Consider arg_int, however arg_int is not used by u8g2
|
||||
*/
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
|
||||
/* The following byte is sent to allow the ST7920 to sync up with the data */
|
||||
/* it solves some issues with garbage data */
|
||||
u8x8_cad_SendCmd(u8x8, 0x03e ); /* enable extended mode */
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
//u8x8_cad_SendCmd(u8x8, 0x03e ); /* enable extended mode */
|
||||
u8x8_cad_SendCmd(u8x8, 0x080 | (y+i) ); /* y pos */
|
||||
u8x8_cad_SendCmd(u8x8, 0x080 | x ); /* set x pos */
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
|
||||
|
||||
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes, send one line of data */
|
||||
ptr += c;
|
||||
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
|
||||
}
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7920_192x32_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1,
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 5,
|
||||
/* pre_chip_disable_wait_ns = */ 5,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140, /* datasheet ST7920 */
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 3, /* old: sck_takeover_edge, new: active high (bit 1), rising edge (bit 0), 18 Aug 16: changed from 1 to 3 which works for 101 */
|
||||
/* Arduino mode 3: aktive low clock, but use rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30,
|
||||
/* write_pulse_width_ns = */ 40,
|
||||
/* tile_width = */ 24,
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 192,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
static const u8x8_display_info_t u8x8_st7920_128x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1,
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 5,
|
||||
/* pre_chip_disable_wait_ns = */ 5,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140, /* datasheet ST7920 */
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* ST7920+Due work with 1MHz but not with 2MHz, ST7920+Uno works with 2MHz */
|
||||
/* spi_mode = */ 3, /* active high, rising edge, 18 Aug 16: changed from 1 to 3 which works for 101 */
|
||||
/* in theory mode 3 should be correct */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30,
|
||||
/* write_pulse_width_ns = */ 40,
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_st7920_192x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7920_192x32_display_info);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8x8_d_st7920_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7920_128x64_display_info);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
|
||||
u8x8_d_stdio.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define W 8
|
||||
#define H 2
|
||||
|
||||
uint8_t bitmap[W*H*8];
|
||||
|
||||
void bitmap_place_tile(uint8_t x, uint8_t y, uint8_t *tile)
|
||||
{
|
||||
uint8_t i;
|
||||
for(i = 0; i < 8; i++ )
|
||||
bitmap[x*8+y*W*8+i] = tile[i];
|
||||
}
|
||||
|
||||
void bitmap_show(void)
|
||||
{
|
||||
int x, y;
|
||||
for( y = 0; y < H*8; y++ )
|
||||
{
|
||||
for( x = 0; x < W*8; x++ )
|
||||
{
|
||||
if ( (bitmap[x+(y/8)*W*8] & (1<<((y&7)))) != 0 )
|
||||
{
|
||||
printf("*");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t u8x8_d_stdio(U8X8_UNUSED u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
bitmap_show();
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
bitmap_place_tile(((u8x8_tile_t *)arg_ptr)->x_pos, ((u8x8_tile_t *)arg_ptr)->y_pos, ((u8x8_tile_t *)arg_ptr)->tile_ptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void u8x8_SetupStdio(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8_SetupDefaults(u8x8);
|
||||
u8x8->display_cb = u8x8_d_stdio;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
|
||||
u8x8_d_t6963.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, olikraus@gmail.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
The t6963 controller does not support hardware graphics flip.
|
||||
Contrast adjustment is done by an external resistor --> no support for contrast adjustment
|
||||
|
||||
|
||||
*/
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_t6963_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x098), /* mode register: Display Mode, Graphics on, Text off, Cursor off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_t6963_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x090), /* All Off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_t6963_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t c, i;
|
||||
uint16_t y;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
|
||||
/*
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
y*=8;
|
||||
y*= u8x8->display_info->tile_width;
|
||||
/* x = ((u8x8_tile_t *)arg_ptr)->x_pos; x is ignored... no u8x8 support */
|
||||
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
|
||||
/*
|
||||
Tile structure is reused here for the t6963, however u8x8 is not supported
|
||||
tile_ptr points to data which has cnt*8 bytes (same as SSD1306 tiles)
|
||||
Buffer is expected to have 8 lines of code fitting to the t6963 internal memory
|
||||
"cnt" includes the number of horizontal bytes. width is equal to cnt*8
|
||||
|
||||
TODO: Consider arg_int, however arg_int is not used by u8g2
|
||||
*/
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
u8x8_cad_SendArg(u8x8, y&255);
|
||||
u8x8_cad_SendArg(u8x8, y>>8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x024 ); /* set adr */
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 ); /* auto write start */
|
||||
|
||||
|
||||
//c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes, send one line of data */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b2 ); /* auto write reset */
|
||||
ptr += u8x8->display_info->tile_width;
|
||||
y += u8x8->display_info->tile_width;
|
||||
}
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=============================================*/
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_t6963_240x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 110, /* T6963 Datasheet p30 */
|
||||
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140,
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0,
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 80,
|
||||
/* write_pulse_width_ns = */ 80,
|
||||
/* tile_width = */ 30,
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
/* 240x128 */
|
||||
static const uint8_t u8x8_d_t6963_240x128_init_seq[] = {
|
||||
U8X8_DLY(100),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(100),
|
||||
|
||||
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
|
||||
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
|
||||
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
|
||||
U8X8_AAC(240/8,0x00,0x041), /* low, high, set text columns */
|
||||
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
|
||||
U8X8_AAC(240/8,0x00,0x043), /* low, high, graphics columns */
|
||||
U8X8_DLY(2), /* delay 2ms */
|
||||
// mode set
|
||||
// 0x080: Internal CG, OR Mode
|
||||
// 0x081: Internal CG, EXOR Mode
|
||||
// 0x083: Internal CG, AND Mode
|
||||
// 0x088: External CG, OR Mode
|
||||
// 0x089: External CG, EXOR Mode
|
||||
// 0x08B: External CG, AND Mode
|
||||
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
|
||||
// display mode
|
||||
// 0x090: Display off
|
||||
// 0x094: Graphic off, text on, cursor off, blink off
|
||||
// 0x096: Graphic off, text on, cursor on, blink off
|
||||
// 0x097: Graphic off, text on, cursor on, blink on
|
||||
// 0x098: Graphic on, text off, cursor off, blink off
|
||||
// 0x09a: Graphic on, text off, cursor on, blink off
|
||||
// ...
|
||||
// 0x09c: Graphic on, text on, cursor off, blink off
|
||||
// 0x09f: Graphic on, text on, cursor on, blink on
|
||||
U8X8_C(0x090), /* All Off */
|
||||
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
|
||||
|
||||
U8X8_DLY(100),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_DLY(100),
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_t6963_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_240x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_240x128_init_seq);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_t6963_240x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 110, /* T6963 Datasheet p30 */
|
||||
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140,
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0,
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 80,
|
||||
/* write_pulse_width_ns = */ 80,
|
||||
/* tile_width = */ 30,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
|
||||
/* 240x64 */
|
||||
static const uint8_t u8x8_d_t6963_240x64_init_seq[] = {
|
||||
U8X8_DLY(100),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(100),
|
||||
|
||||
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
|
||||
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
|
||||
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
|
||||
U8X8_AAC(240/8,0x00,0x041), /* low, high, set text columns */
|
||||
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
|
||||
U8X8_AAC(240/8,0x00,0x043), /* low, high, graphics columns */
|
||||
U8X8_DLY(2), /* delay 2ms */
|
||||
// mode set
|
||||
// 0x080: Internal CG, OR Mode
|
||||
// 0x081: Internal CG, EXOR Mode
|
||||
// 0x083: Internal CG, AND Mode
|
||||
// 0x088: External CG, OR Mode
|
||||
// 0x089: External CG, EXOR Mode
|
||||
// 0x08B: External CG, AND Mode
|
||||
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
|
||||
// display mode
|
||||
// 0x090: Display off
|
||||
// 0x094: Graphic off, text on, cursor off, blink off
|
||||
// 0x096: Graphic off, text on, cursor on, blink off
|
||||
// 0x097: Graphic off, text on, cursor on, blink on
|
||||
// 0x098: Graphic on, text off, cursor off, blink off
|
||||
// 0x09a: Graphic on, text off, cursor on, blink off
|
||||
// ...
|
||||
// 0x09c: Graphic on, text on, cursor off, blink off
|
||||
// 0x09f: Graphic on, text on, cursor on, blink on
|
||||
U8X8_C(0x090), /* All Off */
|
||||
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
|
||||
|
||||
U8X8_DLY(100),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_DLY(100),
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_t6963_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_240x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_240x64_init_seq);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_t6963_256x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 110, /* T6963 Datasheet p30 */
|
||||
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140,
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0,
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 80,
|
||||
/* write_pulse_width_ns = */ 80,
|
||||
/* tile_width = */ 32,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 256,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
/* 256x64 */
|
||||
static const uint8_t u8x8_d_t6963_256x64_init_seq[] = {
|
||||
U8X8_DLY(100),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(100),
|
||||
|
||||
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
|
||||
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
|
||||
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
|
||||
U8X8_AAC(256/8,0x00,0x041), /* low, high, set text columns */
|
||||
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
|
||||
U8X8_AAC(256/8,0x00,0x043), /* low, high, graphics columns */
|
||||
U8X8_DLY(2), /* delay 2ms */
|
||||
// mode set
|
||||
// 0x080: Internal CG, OR Mode
|
||||
// 0x081: Internal CG, EXOR Mode
|
||||
// 0x083: Internal CG, AND Mode
|
||||
// 0x088: External CG, OR Mode
|
||||
// 0x089: External CG, EXOR Mode
|
||||
// 0x08B: External CG, AND Mode
|
||||
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
|
||||
// display mode
|
||||
// 0x090: Display off
|
||||
// 0x094: Graphic off, text on, cursor off, blink off
|
||||
// 0x096: Graphic off, text on, cursor on, blink off
|
||||
// 0x097: Graphic off, text on, cursor on, blink on
|
||||
// 0x098: Graphic on, text off, cursor off, blink off
|
||||
// 0x09a: Graphic on, text off, cursor on, blink off
|
||||
// ...
|
||||
// 0x09c: Graphic on, text on, cursor off, blink off
|
||||
// 0x09f: Graphic on, text on, cursor on, blink on
|
||||
U8X8_C(0x090), /* All Off */
|
||||
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
|
||||
|
||||
U8X8_DLY(100),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_DLY(100),
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_t6963_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_256x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_256x64_init_seq);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_t6963_128x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1,
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* T6963 Datasheet p30 */
|
||||
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 20,
|
||||
/* sck_pulse_width_ns = */ 140,
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0,
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 80,
|
||||
/* write_pulse_width_ns = */ 80,
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
/* 128x64 */
|
||||
static const uint8_t u8x8_d_t6963_128x64_init_seq[] = {
|
||||
U8X8_DLY(100),
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(100),
|
||||
|
||||
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
|
||||
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
|
||||
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
|
||||
U8X8_AAC(128/8,0x00,0x041), /* low, high, set text columns */
|
||||
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
|
||||
U8X8_AAC(128/8,0x00,0x043), /* low, high, graphics columns */
|
||||
U8X8_DLY(2), /* delay 2ms */
|
||||
// mode set
|
||||
// 0x080: Internal CG, OR Mode
|
||||
// 0x081: Internal CG, EXOR Mode
|
||||
// 0x083: Internal CG, AND Mode
|
||||
// 0x088: External CG, OR Mode
|
||||
// 0x089: External CG, EXOR Mode
|
||||
// 0x08B: External CG, AND Mode
|
||||
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
|
||||
// display mode
|
||||
// 0x090: Display off
|
||||
// 0x094: Graphic off, text on, cursor off, blink off
|
||||
// 0x096: Graphic off, text on, cursor on, blink off
|
||||
// 0x097: Graphic off, text on, cursor on, blink on
|
||||
// 0x098: Graphic on, text off, cursor off, blink off
|
||||
// 0x09a: Graphic on, text off, cursor on, blink off
|
||||
// ...
|
||||
// 0x09c: Graphic on, text on, cursor off, blink off
|
||||
// 0x09f: Graphic on, text on, cursor on, blink on
|
||||
U8X8_C(0x090), /* All Off */
|
||||
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
|
||||
|
||||
U8X8_DLY(100),
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_DLY(100),
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_t6963_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_128x64_init_seq);
|
||||
break;
|
||||
default:
|
||||
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1601.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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.
|
||||
|
||||
This is for the uc1601s controller
|
||||
|
||||
|
||||
*/
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1601_128x32_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1601_128x32_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1601_128x32_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c4), /* bit 1: MX, bit 2: MY */
|
||||
U8X8_C(0x060), /* set display start line to 32 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1601_128x32_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c2), /* bit 1: MX, bit 2: MY */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1601_128x32_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 1, /* uc1601 datasheet, page 46 */
|
||||
/* pre_chip_disable_wait_ns = */ 5, /* uc1601 datasheet, page 46 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 12, /* uc1601 datasheet, page 44 */
|
||||
/* sck_pulse_width_ns = */ 15, /* uc1601 datasheet, page 44 */
|
||||
/* sck_clock_hz = */ 2000000UL, /* */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 1,
|
||||
/* data_setup_time_ns = */ 60, /* uc1601 datasheet, page 43 */
|
||||
/* write_pulse_width_ns = */ 80, /* uc1601 datasheet, page 43 */
|
||||
/* tile_width = */ 16,
|
||||
/* tile_hight = */ 4,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 4,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 32
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1601_128x32_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0eb), /* LCD Bias: 0xe8: 6, 0xe9: 7, 0xea: 8, 0xeb: 9 */
|
||||
//U8X8_C(0x023), /* 0x020...0x023 only for UC1601, not for UC1601s */
|
||||
|
||||
|
||||
//U8X8_C(0x02e), /* LCD Load + Internal Charge Pump (default: 0x2e) */
|
||||
U8X8_C(0x024), /* Temperature Compenstation, default: 0x24 */
|
||||
U8X8_C(0x089), /* RAM address ctrl, default: 0x89 */
|
||||
U8X8_C(0x0c4), /* RAM mapping ctrl */
|
||||
U8X8_C(0x0a0), /* Frame Rate, 0x0a0 or 0x0a1 */
|
||||
U8X8_CA(0x081, 0x0df), /* set contrast */
|
||||
U8X8_C(0x02e), /* LCD Load + Internal Charge Pump (default: 0x2e) */
|
||||
U8X8_C(0x060), /* set display start line to 32 */
|
||||
|
||||
U8X8_C(0x0a6), /* normal display */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1601_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1601_128x32_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1601 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1604.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1604_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_DLY(20),
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_DLY(20), /* during setup, it seems that the startup is more reliable when sending this cmd twice */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_DLY(50), /* startup takes some time */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1604_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off, enter sleep mode */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1604_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c4), /* LCD Mapping */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1604_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c2), /* LCD Mapping */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_uc1604_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
|
||||
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
|
||||
y += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (y&15));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
/* handled in the calling procedure
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1604_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1604 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* JLX19264 */
|
||||
|
||||
/*
|
||||
timings from uc1608
|
||||
|
||||
UC1604 has two chip select inputs (CS0 and CS1).
|
||||
CS0 is low active, CS1 is high active. It will depend on the display
|
||||
module whether the display has a is low or high active chip select.
|
||||
|
||||
*/
|
||||
static const u8x8_display_info_t u8x8_uc1604_192x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0, /* JLX19264G uses CS0, which is low active CS*/
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 20,
|
||||
/* pre_chip_disable_wait_ns = */ 20,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 10,
|
||||
/* sda_setup_time_ns = */ 30,
|
||||
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30,
|
||||
/* write_pulse_width_ns = */ 35,
|
||||
/* tile_width = */ 24, /* width of 24*8=192 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0, /* reused as y page offset */
|
||||
/* flipmode_x_offset = */ 0, /* reused as y page offset */
|
||||
/* pixel_width = */ 192,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1604_jlx19264_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_DLY(200),
|
||||
U8X8_DLY(200),
|
||||
|
||||
U8X8_C(0x02f), /* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
|
||||
U8X8_DLY(200),
|
||||
U8X8_DLY(200),
|
||||
|
||||
U8X8_CA(0x081, 0x052), /* set contrast, JLX19264G suggestion: 0x045 */
|
||||
U8X8_C(0x0eb), /* LCD bias Bits 0/1: 00=6 01=7, 10=8, 11=9 */
|
||||
|
||||
|
||||
//U8X8_C(0x023), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
|
||||
//U8X8_C(0x027), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
|
||||
|
||||
U8X8_C(0x0c4), /* Map control, Bit 2: MY=1, Bit 1: MX=0 */
|
||||
U8X8_C(0x0a0), /* 0xa0: 76Hz FPS, controller default: 0x0a1: 95Hz FPS */
|
||||
|
||||
|
||||
U8X8_C(0x040), /* set scroll line to 0 */
|
||||
U8X8_C(0x089), /* RAM access control (controller default: 0x089)*/
|
||||
|
||||
|
||||
U8X8_C(0x000), /* column low nibble */
|
||||
U8X8_C(0x010), /* column high nibble */
|
||||
U8X8_C(0x0b0), /* page adr */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1604_jlx19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_uc1604_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1604_192x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_jlx19264_init_seq);
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1608.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1608_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1608_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off, enter sleep mode */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1608_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c8), /* LCD Mapping */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1608_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c4), /* LCD Mapping */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_uc1608_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
|
||||
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
|
||||
y += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (y&15));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
/* handled in the calling procedure
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1608_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1608 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* ERC24064-1 */
|
||||
|
||||
/*
|
||||
The UC1608 has only one high active chip select input.
|
||||
UC1604, UC1610 and UC1611 have two chip select inputs.
|
||||
*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1608_240x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1, /* uc1608 has high active CS */
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* uc1608 datasheet, page 39, actually 0 */
|
||||
/* pre_chip_disable_wait_ns = */ 20, /* uc1608 datasheet, page 39 */
|
||||
/* reset_pulse_width_ms = */ 1, /* uc1608 datasheet, page 42 */
|
||||
/* post_reset_wait_ms = */ 10,
|
||||
/* sda_setup_time_ns = */ 30, /* uc1608 datasheet, page 41 */
|
||||
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30, /* uc1608 datasheet, page 39 */
|
||||
/* write_pulse_width_ns = */ 35, /* uc1608 datasheet, page 39 */
|
||||
/* tile_width = */ 30, /* width of 30*8=240 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0, /* reused as y page offset */
|
||||
/* flipmode_x_offset = */ 4, /* reused as y page offset */
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1608_erc24064_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_DLY(200),
|
||||
|
||||
U8X8_C(0x023), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
|
||||
//U8X8_C(0x027), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
|
||||
|
||||
U8X8_C(0x0c8), /* Map control, Bit 3: MY=1, Bit 2: MX=0, Bit 0: MSF =0 */
|
||||
U8X8_C(0x0e8), /* LCD bias Bits 0/1: 00=10.7 01=10.3, 10=12.0, 11=12.7 */
|
||||
|
||||
U8X8_C(0x02f), /* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_C(0x090), /* no fixed lines */
|
||||
U8X8_C(0x089), /* RAM access control */
|
||||
|
||||
U8X8_CA(0x081, 0x014), /* set contrast, ERC24064-1 default: 0x040 */
|
||||
|
||||
U8X8_C(0x000), /* column low nibble */
|
||||
U8X8_C(0x010), /* column high nibble */
|
||||
U8X8_C(0x0b0), /* page adr */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1608_erc24064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_uc1608_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1608_240x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_erc24064_init_seq);
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* experimental implementation for the uc1608 240x128, not referenced in codebuild */
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1608_240x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1, /* uc1608 has high active CS */
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* uc1608 datasheet, page 39, actually 0 */
|
||||
/* pre_chip_disable_wait_ns = */ 20, /* uc1608 datasheet, page 39 */
|
||||
/* reset_pulse_width_ms = */ 1, /* uc1608 datasheet, page 42 */
|
||||
/* post_reset_wait_ms = */ 10,
|
||||
/* sda_setup_time_ns = */ 30, /* uc1608 datasheet, page 41 */
|
||||
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30, /* uc1608 datasheet, page 39 */
|
||||
/* write_pulse_width_ns = */ 35, /* uc1608 datasheet, page 39 */
|
||||
/* tile_width = */ 30, /* width of 30*8=240 pixel */
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0, /* reused as y page offset */
|
||||
/* flipmode_x_offset = */ 0, /* reused as y page offset */
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1608_240x128_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_DLY(200),
|
||||
|
||||
//U8X8_C(0x023), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
|
||||
U8X8_C(0x026), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
|
||||
|
||||
U8X8_C(0x0c8), /* Map control, Bit 3: MY=1, Bit 2: MX=0, Bit 0: MSF =0 */
|
||||
U8X8_C(0x0ea), /* LCD bias Bits 0/1: 00=10.7 01=10.3, 10=12.0, 11=12.7 */
|
||||
/* maybe 0x0eb??? */
|
||||
|
||||
U8X8_C(0x02f), /* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_C(0x090), /* no fixed lines */
|
||||
U8X8_C(0x089), /* RAM access control */
|
||||
|
||||
U8X8_CA(0x081, 0x072), /* set contrast */
|
||||
|
||||
U8X8_C(0x000), /* column low nibble */
|
||||
U8X8_C(0x010), /* column high nibble */
|
||||
U8X8_C(0x0b0), /* page adr */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1608_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_uc1608_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1608_240x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_240x128_init_seq);
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* experimental implementation for the uc1608 erc240x120 */
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1608_erc240120_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1, /* uc1608 has high active CS */
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* uc1608 datasheet, page 39, actually 0 */
|
||||
/* pre_chip_disable_wait_ns = */ 20, /* uc1608 datasheet, page 39 */
|
||||
/* reset_pulse_width_ms = */ 1, /* uc1608 datasheet, page 42 */
|
||||
/* post_reset_wait_ms = */ 10,
|
||||
/* sda_setup_time_ns = */ 30, /* uc1608 datasheet, page 41 */
|
||||
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30, /* uc1608 datasheet, page 39 */
|
||||
/* write_pulse_width_ns = */ 35, /* uc1608 datasheet, page 39 */
|
||||
/* tile_width = */ 30, /* width of 30*8=240 pixel */
|
||||
/* tile_hight = */ 15,
|
||||
/* default_x_offset = */ 1, /* reused as y page offset */
|
||||
/* flipmode_x_offset = */ 0, /* reused as y page offset */
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 120
|
||||
};
|
||||
|
||||
/* http://www.buydisplay.com/download/democode/ERC240120-1_DemoCode.txt */
|
||||
static const uint8_t u8x8_d_uc1608_erc240120_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_DLY(200),
|
||||
|
||||
//U8X8_C(0x023), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
|
||||
U8X8_C(0x026), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
|
||||
|
||||
U8X8_C(0x0c8), /* Map control, Bit 3: MY=1, Bit 2: MX=0, Bit 0: MSF =0 */
|
||||
U8X8_C(0x0ea), /* LCD bias Bits 0/1: 00=10.7 01=10.3, 10=12.0, 11=12.7 */
|
||||
/* according to DemoCode.txt */
|
||||
|
||||
U8X8_C(0x02f), /* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
|
||||
U8X8_DLY(50),
|
||||
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
U8X8_C(0x090), /* no fixed lines */
|
||||
U8X8_C(0x089), /* RAM access control */
|
||||
|
||||
//U8X8_CA(0x081, 46), /* set contrast, 46 according to DemoCode.txt */
|
||||
U8X8_CA(0x081, 80), /* */
|
||||
|
||||
U8X8_C(0x000), /* column low nibble */
|
||||
U8X8_C(0x010), /* column high nibble */
|
||||
U8X8_C(0x0b0), /* page adr */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1608_erc240120(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_uc1608_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1608_erc240120_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_erc240120_init_seq);
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1610.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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.
|
||||
|
||||
|
||||
cad001
|
||||
|
||||
*/
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1610_dogxl160_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_CA(0x0f1, 0x067), /* set COM end (display height-1) */
|
||||
U8X8_C(0x0c0), /* SEG & COM normal */
|
||||
U8X8_C(0x040), /* set scroll line lsb to zero */
|
||||
U8X8_C(0x050), /* set scroll line msb to zero */
|
||||
U8X8_C(0x02b), /* set panelloading */
|
||||
U8X8_C(0x0eb), /* set bias 1/2 */
|
||||
U8X8_CA(0x081, 0x05f), /* set contrast */
|
||||
|
||||
/*
|
||||
AC0: 0: stop at boundary, 1: increment by one
|
||||
AC1: 0: first column then page, 1: first page, then column increment
|
||||
AC2: 0: increment page adr, 1: decrement page adr.
|
||||
*/
|
||||
U8X8_C(0x08b), /* set auto increment, low bits are AC2 AC1 AC0 */
|
||||
|
||||
/*
|
||||
LC0: 0
|
||||
MX: Mirror X
|
||||
MY: Mirror Y
|
||||
*/
|
||||
U8X8_C(0x0c0), /* low bits are MY, MX, LC0 */
|
||||
|
||||
U8X8_C(0x0f8), // window mode off
|
||||
U8X8_C(0x010), // col high
|
||||
U8X8_C(0x000), // col low
|
||||
U8X8_C(0x0b0), // page
|
||||
|
||||
U8X8_C(0x0a6), /* set normal pixel mode (not inverse) */
|
||||
U8X8_C(0x0a4), /* set normal pixel mode (not all on) */
|
||||
|
||||
/* test code
|
||||
U8X8_C(0x0af), // display on
|
||||
U8X8_C(0x0f8), // window mode off
|
||||
U8X8_CA(0x0f4, 0), // set window
|
||||
U8X8_CA(0x0f5, 0),
|
||||
U8X8_CA(0x0f6, 4),
|
||||
U8X8_CA(0x0f7, 1),
|
||||
U8X8_C(0x0f9), // window mode on
|
||||
U8X8_D1(0x03),
|
||||
U8X8_D1(0x0c0),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
*/
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1610_dogxl160_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on, UC1610 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1610_dogxl160_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off, UC1610 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1610_dogxl160_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
/*
|
||||
LC0: 0
|
||||
MX: Mirror X
|
||||
MY: Mirror Y
|
||||
*/
|
||||
U8X8_C(0x0c0), /* low bits are MY, MX, LC0 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1610_dogxl160_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
/*
|
||||
LC0: 0
|
||||
MX: Mirror X
|
||||
MY: Mirror Y
|
||||
*/
|
||||
U8X8_C(0x0c6), /* low bits are MY, MX, LC0 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
UC1610 has two chip select inputs (CS0 and CS1).
|
||||
CS0 is low active, CS1 is high active. It will depend on the display
|
||||
module whether the display has a is low or high active chip select.
|
||||
*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1610_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 15,
|
||||
/* pre_chip_disable_wait_ns = */ 15,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 30,
|
||||
/* sck_pulse_width_ns = */ 63, /* half of cycle time (125ns cycle time according to datasheet) --> 8MHz clock */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30,
|
||||
/* write_pulse_width_ns = */ 40,
|
||||
/* tile_width = */ 20,
|
||||
/* tile_hight = */ 13, /* height of 13*8=104 pixel */
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 160,
|
||||
/* pixel_height = */ 104
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
RAM Organization:
|
||||
D0 Pix0
|
||||
D1
|
||||
D2 Pix1
|
||||
D3
|
||||
D4 Pix2
|
||||
D5
|
||||
D6 Pix3
|
||||
D7
|
||||
D0 Pix4
|
||||
D1
|
||||
D2 Pix5
|
||||
D3
|
||||
D4 Pix6
|
||||
D5
|
||||
D6 Pix7
|
||||
D7
|
||||
|
||||
|
||||
*/
|
||||
static uint8_t *u8x8_convert_tile_for_uc1610(uint8_t *t)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t r;
|
||||
static uint8_t buf[16];
|
||||
uint8_t *pbuf = buf;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
r = u8x8_upscale_byte(*t++);
|
||||
*pbuf++ = r & 255;
|
||||
r >>= 8;
|
||||
*pbuf++ = r;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
uint8_t u8x8_d_uc1610_ea_dogxl160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c, page;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1610_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* uc1610 has range from 0 to 63 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
page = (((u8x8_tile_t *)arg_ptr)->y_pos);
|
||||
page *= 2;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x0f8 ); /* window disable */
|
||||
|
||||
//u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
//u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
//u8x8_cad_SendCmd(u8x8, 0x0b0 | page);
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x0f4 ); /* window start column */
|
||||
u8x8_cad_SendArg(u8x8, x);
|
||||
u8x8_cad_SendCmd(u8x8, 0x0f5 ); /* window start page */
|
||||
u8x8_cad_SendArg(u8x8, page);
|
||||
u8x8_cad_SendCmd(u8x8, 0x0f6 ); /* window end column */
|
||||
u8x8_cad_SendArg(u8x8, 159); /* end of display */
|
||||
u8x8_cad_SendCmd(u8x8, 0x0f7 ); /* window end page */
|
||||
u8x8_cad_SendArg(u8x8, page+1);
|
||||
u8x8_cad_SendCmd(u8x8, 0x0f9 ); /* window enable */
|
||||
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
|
||||
|
||||
u8x8_cad_SendData(u8x8, 16, u8x8_convert_tile_for_uc1610(ptr));
|
||||
|
||||
|
||||
ptr += 8;
|
||||
x += 8;
|
||||
c--;
|
||||
} while( c > 0 );
|
||||
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,502 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1611.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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.
|
||||
|
||||
|
||||
6 Nov 2016: Not yet finished
|
||||
|
||||
There are two controller:
|
||||
UC1611s 160x256
|
||||
UC1611 160x240
|
||||
|
||||
Differences:
|
||||
UC1611 0xa8 cmd: enables 80 display rows
|
||||
UC1611s 0xa8 cmd: controlls graylevels
|
||||
|
||||
UC1611 0xc0 cmd: single byte command for LCD mapping control
|
||||
UC1611s 0xc0 cmd: double byte command for LCD mapping control
|
||||
|
||||
|
||||
*/
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1611s_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a9), /* display on, UC1611s */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1611s_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a8), /* display off, enter sleep mode, UC1611s */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1611s_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0c0, 0x004), /* LCD Mapping */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1611s_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0c0, 0x002), /* LCD Mapping */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1611_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
|
||||
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
|
||||
u8x8_cad_SendCmd(u8x8, 0x060 | (y&15));
|
||||
u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
/* handled in the calling procedure
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
|
||||
break;
|
||||
*/
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1611 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* EA DOGM240 */
|
||||
|
||||
|
||||
/*
|
||||
UC1611 has two chip select inputs (CS0 and CS1).
|
||||
CS0 is low active, CS1 is high active. It will depend on the display
|
||||
module whether the display has a is low or high active chip select.
|
||||
*/
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1611_240x64_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
|
||||
/* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */
|
||||
/* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */
|
||||
/* sck_pulse_width_ns = */ 60, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */
|
||||
/* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */
|
||||
/* tile_width = */ 30, /* width of 30*8=240 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1611_ea_dogm240_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x02f), /* internal pump control */
|
||||
U8X8_CA(0x0f1, 63), /* set COM end */
|
||||
U8X8_CA(0x0f2, 0x000), /* display line start */
|
||||
U8X8_CA(0x0f3, 63), /* display line end */
|
||||
U8X8_C(0x0a3), /* line rate */
|
||||
U8X8_CA(0x081, 0x0a4), /* set contrast, EA default: 0x0b7 */
|
||||
|
||||
//U8X8_C(0x0a9), /* display enable */
|
||||
|
||||
U8X8_C(0x0d1), /* display pattern */
|
||||
U8X8_C(0x089), /* auto increment */
|
||||
U8X8_CA(0x0c0, 0x004), /* LCD Mapping */
|
||||
U8X8_C(0x000), /* column low nibble */
|
||||
U8X8_C(0x010), /* column high nibble */
|
||||
U8X8_C(0x060), /* page adr low */
|
||||
U8X8_C(0x070), /* page adr high */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
/* UC1611s 240x64 display */
|
||||
uint8_t u8x8_d_uc1611_ea_dogm240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_uc1611_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_240x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ea_dogm240_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* EA DOGXL240 */
|
||||
|
||||
static const uint8_t u8x8_d_uc1611_ea_dogxl240_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x02f), /* internal pump control */
|
||||
U8X8_CA(0x0f1, 0x07f), /* set COM end */
|
||||
U8X8_CA(0x0f2, 0x000), /* display line start */
|
||||
U8X8_CA(0x0f3, 127), /* display line end */
|
||||
U8X8_C(0x0a3), /* line rate */
|
||||
U8X8_CA(0x081, 0x08f), /* set contrast */
|
||||
|
||||
//U8X8_C(0x0a9), /* display enable */
|
||||
|
||||
U8X8_C(0x0d1), /* display pattern */
|
||||
U8X8_C(0x089), /* auto increment */
|
||||
U8X8_CA(0x0c0, 0x004), /* LCD Mapping */
|
||||
U8X8_C(0x000), /* column low nibble */
|
||||
U8X8_C(0x010), /* column high nibble */
|
||||
U8X8_C(0x060), /* page adr low */
|
||||
U8X8_C(0x070), /* page adr high */
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1611_240x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
|
||||
/* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */
|
||||
/* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */
|
||||
/* sck_pulse_width_ns = */ 60, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */
|
||||
/* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */
|
||||
/* tile_width = */ 30, /* width of 30*8=240 pixel */
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
/* UC1611s 240x128 display */
|
||||
uint8_t u8x8_d_uc1611_ea_dogxl240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_uc1611_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_240x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ea_dogxl240_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* EMERGING DISPLAY, EW50850FLWP 240x160 */
|
||||
/* active high CS (CS1), UC1611 display */
|
||||
|
||||
static const uint8_t u8x8_d_uc1611_ew50850_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x02f), /* internal pump control */
|
||||
U8X8_CA(0x0f1, 159), /* set COM end */
|
||||
U8X8_CA(0x0f2, 0), /* display line start */
|
||||
U8X8_CA(0x0f3, 159), /* display line end */
|
||||
U8X8_C(0x0a3), /* line rate */
|
||||
U8X8_CA(0x081, 75), /* set contrast */
|
||||
|
||||
//U8X8_C(0x0a9), /* display enable */
|
||||
|
||||
U8X8_C(0x0d2), /* gray level mode: 16 gray shades */
|
||||
U8X8_C(0x089), /* auto increment */
|
||||
U8X8_C(0x0c0), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */
|
||||
U8X8_C(0x000), /* column low nibble */
|
||||
U8X8_C(0x010), /* column high nibble */
|
||||
U8X8_C(0x060), /* page adr low */
|
||||
U8X8_C(0x070), /* page adr high */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1611_ew50850_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1, /* active high */
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
|
||||
/* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */
|
||||
/* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */
|
||||
/* sck_pulse_width_ns = */ 60, /* half of cycle time */
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */
|
||||
/* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */
|
||||
/* tile_width = */ 30, /* width of 30*8=240 pixel */
|
||||
/* tile_hight = */ 20, /* height: 160 pixel */
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 240,
|
||||
/* pixel_height = */ 160
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1611_alt_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c0), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1611_alt_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c6), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1611_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0af), /* display on, UC1611 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1611_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a8), /* display off, enter sleep mode, UC1611 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
/* EW50850, 240x160 */
|
||||
uint8_t u8x8_d_uc1611_ew50850(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c, i, v, m0, m1, ai;
|
||||
uint8_t *ptr;
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
|
||||
y*=4;
|
||||
m0 = 1;
|
||||
m1 = 2;
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x060 | (y&15));
|
||||
u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4));
|
||||
|
||||
ai = arg_int;
|
||||
do
|
||||
{
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
while( c > 0 )
|
||||
{
|
||||
v = 0;
|
||||
if ( *ptr & m0 )
|
||||
v|= 0x0f;
|
||||
if ( *ptr & m1 )
|
||||
v|= 0xf0;
|
||||
u8x8_cad_SendData(u8x8, 1, &v); /* note: SendData can not handle more than 255 bytes */
|
||||
c--;
|
||||
ptr++;
|
||||
}
|
||||
ai--;
|
||||
} while( ai > 0 );
|
||||
|
||||
m0 <<= 2;
|
||||
m1 <<= 2;
|
||||
y++;
|
||||
}
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_ew50850_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ew50850_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_alt_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_alt_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1611 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1617.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2017, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1617_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ad), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1617_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ac), /* display off, enter sleep mode */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1617_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c4), /* LCD Mapping */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1617_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c2), /* LCD Mapping */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_uc1617_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
|
||||
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
|
||||
u8x8_cad_SendCmd(u8x8, 0x060 | (y&15));
|
||||
u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1617 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*================================================*/
|
||||
/* JLX128128 */
|
||||
|
||||
static const uint8_t u8x8_d_uc1617_jlx128128_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* reset */
|
||||
U8X8_DLY(10),
|
||||
|
||||
//U8X8_D1(0x0ff),
|
||||
U8X8_C(0x027), /* temperature compensation */
|
||||
U8X8_C(0x02b), /* panel loading: 13-18nF */
|
||||
|
||||
U8X8_C(0x02f), /* internal pump control */
|
||||
U8X8_C(0x0eb), /* bias=1/11 */
|
||||
U8X8_CA(0x081, 0x066), /* set contrast */
|
||||
//U8X8_C(0x0a9), /* used in display datasheet, but cmd not described in controller datasheet */
|
||||
|
||||
U8X8_CA(0x0f1, 0x07f), /* set COM end */
|
||||
U8X8_CA(0x0f2, 0x000), /* display line start */
|
||||
U8X8_CA(0x0f3, 127), /* display line end */
|
||||
U8X8_C(0x0a3), /* line rate */
|
||||
|
||||
U8X8_C(0x0d3), /* */
|
||||
U8X8_C(0x0d7), /* */
|
||||
|
||||
U8X8_C(0x0ad), /* display enable BW Mode*/
|
||||
//U8X8_C(0x0af), /* display enable GS Mode*/
|
||||
|
||||
//U8X8_C(0x0a5), /* all pixel on */
|
||||
|
||||
//U8X8_C(0x0d1), /* display pattern */
|
||||
U8X8_C(0x089), /* auto increment */
|
||||
U8X8_C(0x0c4), /* LCD Mapping */
|
||||
U8X8_C(0x000), /* column */
|
||||
U8X8_C(0x060), /* page adr low */
|
||||
U8X8_C(0x070), /* page adr high */
|
||||
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
U8X8_D1(0x0ff),
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1617_128x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* uc1617 datasheet, page 54, actually 5 */
|
||||
/* pre_chip_disable_wait_ns = */ 10, /* uc1617 datasheet, page 54, actually 5 */
|
||||
/* reset_pulse_width_ms = */ 10,
|
||||
/* post_reset_wait_ms = */ 20, /* uc1617 datasheet, page 56 */
|
||||
/* sda_setup_time_ns = */ 24, /* uc1617 datasheet, page 54 */
|
||||
/* sck_pulse_width_ns = */ 45, /* half of cycle time uc1617 datasheet, page 54*/
|
||||
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30, /* uc1617 datasheet, page 52 */
|
||||
/* write_pulse_width_ns = */ 65, /* uc1617 datasheet, page 52 */
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 0,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1617_jlx128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_uc1617_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1617_128x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_jlx128128_init_seq);
|
||||
for(;;)
|
||||
;
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1638.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1638_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0c9, 0x0ad), /* display on */ /* UC1638 B/W mode */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1638_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_CA(0x0c9, 0x0ac), /* display off */ /* UC1638 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1638_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c4), /* LCD Mapping */ /* UC1638*/
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1638_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0c2), /* LCD Mapping */ /* UC1638*/
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
uint8_t u8x8_d_uc1638_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, y, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x004); /* UC1638 */
|
||||
u8x8_cad_SendArg(u8x8, x);
|
||||
|
||||
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
|
||||
y += u8x8->x_offset;
|
||||
y *= 2; /* for B/W mode, use only every second page */
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x060 | (y&15)); /* UC1638 */
|
||||
u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4)); /* UC1638 */
|
||||
|
||||
|
||||
u8x8_cad_SendCmd(u8x8, 0x001); /* UC1638 */
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
/* handled in the calling procedure
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1638_128x64_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
|
||||
break;
|
||||
*/
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1638 has range from 0 to 255 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
/* uc1638 160x128 */
|
||||
|
||||
/* values taken from uc1608 */
|
||||
static const u8x8_display_info_t u8x8_uc1638_160x128_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 1, /* uc1638 has high active CS */
|
||||
/* chip_disable_level = */ 0,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 10, /* */
|
||||
/* pre_chip_disable_wait_ns = */ 20, /* */
|
||||
/* reset_pulse_width_ms = */ 5, /* */
|
||||
/* post_reset_wait_ms = */ 150,
|
||||
/* sda_setup_time_ns = */ 30, /* */
|
||||
/* sck_pulse_width_ns = */ 65, /* */
|
||||
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 3, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30, /* */
|
||||
/* write_pulse_width_ns = */ 35, /* */
|
||||
/* tile_width = */ 20, /* width of 20*8=160 pixel */
|
||||
/* tile_hight = */ 16,
|
||||
/* default_x_offset = */ 0, /* */
|
||||
/* flipmode_x_offset = */ 0, /* */
|
||||
/* pixel_width = */ 160,
|
||||
/* pixel_height = */ 128
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1638_160x128_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_CA(0x0e1, 0x0e2), /* software reset */ /* UC1638*/
|
||||
U8X8_DLY(5), /* 5 ms */
|
||||
|
||||
U8X8_C(0x024), /* set temp comp*/
|
||||
U8X8_C(0x0c0), /* mirror y and mirror x */ /* WAS: c2 */
|
||||
U8X8_C(0x0a2), /* line rate */
|
||||
U8X8_C(0x0d6), /* gray scale 2 */
|
||||
U8X8_C(0x0eb), /* set bias*/
|
||||
U8X8_C(0x095), /* set 1 bit per pixel, pattern 0*/
|
||||
U8X8_C(0x089), /* set auto increment, low bits are AC2 AC1 AC0 */ /* WAS 89 */
|
||||
|
||||
|
||||
U8X8_CA(0x081, 0x0a0), /* set contrast */ /* UC1638*/
|
||||
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1638_160x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* call common procedure first and handle messages there */
|
||||
if ( u8x8_d_uc1638_common(u8x8, msg, arg_int, arg_ptr) == 0 )
|
||||
{
|
||||
/* msg not handled, then try here */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1638_160x128_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_160x128_init_seq);
|
||||
break;
|
||||
default:
|
||||
return 0; /* msg unknown */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*================================================*/
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1701_dogs102.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_dogs102_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a1), /* ADC set to reverse */
|
||||
U8X8_C(0x0c0), /* common output mode */
|
||||
// Flipmode
|
||||
//U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
//U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a2), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on */
|
||||
U8X8_C(0x027), /* regulator, booster and follower */
|
||||
U8X8_CA(0x081, 0x00e), /* set contrast, contrast value, EA default: 0x010, previous value for S102: 0x0e */
|
||||
U8X8_C(0x0fa), /* Set Temp compensation */
|
||||
U8X8_C(0x090), /* 0.11 deg/c WP Off WC Off*/
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_dogs102_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a4), /* all pixel off, issue 142 */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_dogs102_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_dogs102_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_dogs102_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1701_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 5,
|
||||
/* pre_chip_disable_wait_ns = */ 5,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 12,
|
||||
/* sck_pulse_width_ns = */ 75, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30,
|
||||
/* write_pulse_width_ns = */ 40,
|
||||
/* tile_width = */ 13, /* width of 13*8=104 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 30,
|
||||
/* pixel_width = */ 102,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1701_ea_dogs102(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1701_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* uc1701 has range from 0 to 63 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
/*
|
||||
The following if condition checks the hardware limits of the uc1701
|
||||
controller: It is not allowed to write beyond the display limits.
|
||||
This is in fact an issue within flip mode.
|
||||
*/
|
||||
if ( c + x > 132u )
|
||||
{
|
||||
c = 132u;
|
||||
c -= x;
|
||||
}
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
|
||||
u8x8_d_uc1701_mini12864.c (dealextreme, displays from ebay MP3 players)
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_mini12864_init_seq[] = {
|
||||
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
|
||||
U8X8_C(0x0e2), /* soft reset */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x040), /* set display start line to 0 */
|
||||
|
||||
U8X8_C(0x0a0), /* ADC set to reverse */
|
||||
U8X8_C(0x0c8), /* common output mode */
|
||||
|
||||
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
|
||||
U8X8_C(0x0a2), /* LCD bias 1/9 */
|
||||
U8X8_C(0x02f), /* all power control circuits on */
|
||||
U8X8_C(0x0f8), /* set booster ratio to */
|
||||
U8X8_C(0x000), /* 4x */
|
||||
U8X8_C(0x023), /* set V0 voltage resistor ratio to large */
|
||||
U8X8_C(0x081), /* set contrast */
|
||||
U8X8_C(0x027), /* contrast value */
|
||||
U8X8_C(0x0ac), /* indicator */
|
||||
// 0x000, /* disable */
|
||||
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_mini12864_powersave0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a4), /* all pixel off, issue 142 */
|
||||
U8X8_C(0x0af), /* display on */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_mini12864_powersave1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0ae), /* display off */
|
||||
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_mini12864_flip0_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a0), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
static const uint8_t u8x8_d_uc1701_mini12864_flip1_seq[] = {
|
||||
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
|
||||
U8X8_C(0x0a1), /* segment remap a0/a1*/
|
||||
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
|
||||
U8X8_END_TRANSFER(), /* disable chip */
|
||||
U8X8_END() /* end of sequence */
|
||||
};
|
||||
|
||||
|
||||
static const u8x8_display_info_t u8x8_uc1701_display_info =
|
||||
{
|
||||
/* chip_enable_level = */ 0,
|
||||
/* chip_disable_level = */ 1,
|
||||
|
||||
/* post_chip_enable_wait_ns = */ 5,
|
||||
/* pre_chip_disable_wait_ns = */ 5,
|
||||
/* reset_pulse_width_ms = */ 1,
|
||||
/* post_reset_wait_ms = */ 6,
|
||||
/* sda_setup_time_ns = */ 12,
|
||||
/* sck_pulse_width_ns = */ 75, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
|
||||
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
|
||||
/* spi_mode = */ 0, /* active high, rising edge */
|
||||
/* i2c_bus_clock_100kHz = */ 4,
|
||||
/* data_setup_time_ns = */ 30,
|
||||
/* write_pulse_width_ns = */ 40,
|
||||
/* tile_width = */ 16, /* width of 16*8=128 pixel */
|
||||
/* tile_hight = */ 8,
|
||||
/* default_x_offset = */ 0,
|
||||
/* flipmode_x_offset = */ 4,
|
||||
/* pixel_width = */ 128,
|
||||
/* pixel_height = */ 64
|
||||
};
|
||||
|
||||
uint8_t u8x8_d_uc1701_mini12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t x, c;
|
||||
uint8_t *ptr;
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
|
||||
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1701_display_info);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_INIT:
|
||||
u8x8_d_helper_display_init(u8x8);
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_init_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
|
||||
if ( arg_int == 0 )
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_powersave0_seq);
|
||||
else
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_powersave1_seq);
|
||||
break;
|
||||
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_flip0_seq);
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_flip1_seq);
|
||||
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
|
||||
}
|
||||
break;
|
||||
#ifdef U8X8_WITH_SET_CONTRAST
|
||||
case U8X8_MSG_DISPLAY_SET_CONTRAST:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
u8x8_cad_SendCmd(u8x8, 0x081 );
|
||||
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* uc1701 has range from 0 to 63 */
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
#endif
|
||||
case U8X8_MSG_DISPLAY_DRAW_TILE:
|
||||
u8x8_cad_StartTransfer(u8x8);
|
||||
|
||||
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
|
||||
x *= 8;
|
||||
x += u8x8->x_offset;
|
||||
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
|
||||
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
|
||||
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
|
||||
|
||||
c = ((u8x8_tile_t *)arg_ptr)->cnt;
|
||||
c *= 8;
|
||||
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
|
||||
/*
|
||||
The following if condition checks the hardware limits of the uc1701
|
||||
controller: It is not allowed to write beyond the display limits.
|
||||
This is in fact an issue within flip mode.
|
||||
|
||||
bug: this check should be inside the while loop, see u8x8_d_pcd8544_84x48.c
|
||||
*/
|
||||
if ( c + x > 132u )
|
||||
{
|
||||
c = 132u;
|
||||
c -= x;
|
||||
}
|
||||
do
|
||||
{
|
||||
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
|
||||
arg_int--;
|
||||
} while( arg_int > 0 );
|
||||
|
||||
u8x8_cad_EndTransfer(u8x8);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
|
||||
u8x8_debounce.c
|
||||
|
||||
Key/button simple debounce algorithm (Addon for u8x8)
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
static uint8_t u8x8_read_pin_state(u8x8_t *u8x8)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t pin_state;
|
||||
|
||||
pin_state = 255; /* be compatible with the setup of the default pin setup, which is 255 */
|
||||
for( i = 0; i < U8X8_PIN_INPUT_CNT; i++ )
|
||||
{
|
||||
pin_state <<= 1;
|
||||
|
||||
/* the callback function should put the return value into this variable */
|
||||
u8x8->gpio_result = 1;
|
||||
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO(i+U8X8_PIN_OUTPUT_CNT), 0);
|
||||
pin_state |= u8x8->gpio_result & 1;
|
||||
}
|
||||
|
||||
return pin_state;
|
||||
}
|
||||
|
||||
/*
|
||||
return 0 to U8X8_PIN_INPUT_CNT-1 if there is a difference
|
||||
return U8X8_PIN_INPUT_CNT if there is no difference
|
||||
*/
|
||||
static uint8_t u8x8_find_first_diff(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint8_t mask;
|
||||
uint8_t i;
|
||||
mask = 1;
|
||||
i = U8X8_PIN_INPUT_CNT;
|
||||
do
|
||||
{
|
||||
i--;
|
||||
if ( (a & mask) != (b & mask) )
|
||||
return i;
|
||||
mask <<= 1;
|
||||
} while( i > 0 );
|
||||
return U8X8_PIN_INPUT_CNT;
|
||||
}
|
||||
|
||||
/*
|
||||
State A:
|
||||
u8x8->debounce_last_pin_state == current_state
|
||||
--> State A
|
||||
u8x8->debounce_last_pin_state != current_state
|
||||
--> u8x8->debounce_last_pin_state = current_state
|
||||
--> State B + cnt
|
||||
|
||||
State B + cnt
|
||||
--> state--
|
||||
|
||||
State B
|
||||
u8x8->debounce_last_pin_state == current_state
|
||||
--> keypress detected
|
||||
--> State C
|
||||
u8x8->debounce_last_pin_state != current_state
|
||||
--> State A
|
||||
|
||||
State C
|
||||
u8x8->debounce_last_pin_state == current_state
|
||||
--> State C
|
||||
u8x8->debounce_last_pin_state != current_state
|
||||
--> State A
|
||||
|
||||
*/
|
||||
|
||||
#ifdef __unix__xxxxxx_THIS_IS_DISABLED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
|
||||
{
|
||||
int c;
|
||||
c = getc(stdin);
|
||||
switch(c)
|
||||
{
|
||||
case 'n':
|
||||
return U8X8_MSG_GPIO_MENU_NEXT;
|
||||
case 'p':
|
||||
return U8X8_MSG_GPIO_MENU_PREV;
|
||||
case 's':
|
||||
return U8X8_MSG_GPIO_MENU_SELECT;
|
||||
case 'h':
|
||||
return U8X8_MSG_GPIO_MENU_HOME;
|
||||
case 'x':
|
||||
exit(0);
|
||||
default:
|
||||
puts("press n, p, s, h or x");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else /* __unix__ */
|
||||
|
||||
|
||||
#define U8X8_DEBOUNCE_WAIT 2
|
||||
/* do debounce and return a GPIO msg which indicates the event */
|
||||
/* returns 0, if there is no event */
|
||||
#if defined(__GNUC__) && !defined(__CYGWIN__)
|
||||
# pragma weak u8x8_GetMenuEvent
|
||||
#endif
|
||||
uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
|
||||
{
|
||||
uint8_t pin_state;
|
||||
uint8_t result_msg = 0; /* invalid message, no event */
|
||||
|
||||
pin_state = u8x8_read_pin_state(u8x8);
|
||||
|
||||
/* States A, B, C & D are encoded in the upper 4 bit*/
|
||||
switch(u8x8->debounce_state)
|
||||
{
|
||||
case 0x00: /* State A, default state */
|
||||
if ( u8x8->debounce_default_pin_state != pin_state )
|
||||
{
|
||||
//u8x8->debounce_last_pin_state = pin_state;
|
||||
u8x8->debounce_state = 0x010 + U8X8_DEBOUNCE_WAIT;
|
||||
}
|
||||
break;
|
||||
case 0x10: /* State B */
|
||||
//if ( u8x8->debounce_last_pin_state != pin_state )
|
||||
if ( u8x8->debounce_default_pin_state == pin_state )
|
||||
{
|
||||
u8x8->debounce_state = 0x00; /* back to state A */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* keypress detected */
|
||||
u8x8->debounce_last_pin_state = pin_state;
|
||||
//result_msg = U8X8_MSG_GPIO_MENU_NEXT;
|
||||
u8x8->debounce_state = 0x020 + U8X8_DEBOUNCE_WAIT; /* got to state C */
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x20: /* State C */
|
||||
if ( u8x8->debounce_last_pin_state != pin_state )
|
||||
{
|
||||
u8x8->debounce_state = 0x00; /* back to state A */
|
||||
}
|
||||
else
|
||||
{
|
||||
u8x8->debounce_state = 0x030; /* got to state D */
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x30: /* State D */
|
||||
/* wait until key release */
|
||||
if ( u8x8->debounce_default_pin_state == pin_state )
|
||||
{
|
||||
u8x8->debounce_state = 0x00; /* back to state A */
|
||||
result_msg = U8X8_MSG_GPIO(u8x8_find_first_diff(u8x8->debounce_default_pin_state, u8x8->debounce_last_pin_state)+U8X8_PIN_OUTPUT_CNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
//result_msg = U8X8_MSG_GPIO_MENU_NEXT;
|
||||
// maybe implement autorepeat here
|
||||
}
|
||||
break;
|
||||
default:
|
||||
u8x8->debounce_state--; /* count down, until there is a valid state */
|
||||
break;
|
||||
}
|
||||
return result_msg;
|
||||
}
|
||||
|
||||
#endif /* __unix__ */
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
|
||||
u8x8_display.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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.
|
||||
|
||||
|
||||
Abstraction layer for the graphics controller.
|
||||
Main goal is the placement of a 8x8 pixel block (tile) on the display.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
/* internal library function */
|
||||
|
||||
/*
|
||||
this is a helper function for the U8X8_MSG_DISPLAY_SETUP_MEMORY function.
|
||||
It can be called within the display callback function to carry out the usual standard tasks.
|
||||
|
||||
*/
|
||||
void u8x8_d_helper_display_setup_memory(u8x8_t *u8x8, const u8x8_display_info_t *display_info)
|
||||
{
|
||||
/* 1) set display info struct */
|
||||
u8x8->display_info = display_info;
|
||||
u8x8->x_offset = u8x8->display_info->default_x_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
this is a helper function for the U8X8_MSG_DISPLAY_INIT function.
|
||||
It can be called within the display callback function to carry out the usual standard tasks.
|
||||
|
||||
*/
|
||||
void u8x8_d_helper_display_init(u8x8_t *u8x8)
|
||||
{
|
||||
/* 2) apply port directions to the GPIO lines and apply default values for the IO lines*/
|
||||
u8x8_gpio_Init(u8x8);
|
||||
u8x8_cad_Init(u8x8);
|
||||
|
||||
/* 3) do reset */
|
||||
u8x8_gpio_SetReset(u8x8, 1);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms);
|
||||
u8x8_gpio_SetReset(u8x8, 0);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms);
|
||||
u8x8_gpio_SetReset(u8x8, 1);
|
||||
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->post_reset_wait_ms);
|
||||
}
|
||||
|
||||
/*==========================================*/
|
||||
/* official functions */
|
||||
|
||||
uint8_t u8x8_DrawTile(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr)
|
||||
{
|
||||
u8x8_tile_t tile;
|
||||
tile.x_pos = x;
|
||||
tile.y_pos = y;
|
||||
tile.cnt = cnt;
|
||||
tile.tile_ptr = tile_ptr;
|
||||
return u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, 1, (void *)&tile);
|
||||
}
|
||||
|
||||
/* should be implemented as macro */
|
||||
void u8x8_SetupMemory(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SETUP_MEMORY, 0, NULL);
|
||||
}
|
||||
|
||||
void u8x8_InitDisplay(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL);
|
||||
}
|
||||
|
||||
void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable)
|
||||
{
|
||||
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_POWER_SAVE, is_enable, NULL);
|
||||
}
|
||||
|
||||
void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode)
|
||||
{
|
||||
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, mode, NULL);
|
||||
}
|
||||
|
||||
void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value)
|
||||
{
|
||||
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_CONTRAST, value, NULL);
|
||||
}
|
||||
|
||||
void u8x8_RefreshDisplay(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_REFRESH, 0, NULL);
|
||||
}
|
||||
|
||||
void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf)
|
||||
{
|
||||
u8x8_tile_t tile;
|
||||
uint8_t h;
|
||||
|
||||
tile.x_pos = 0;
|
||||
tile.cnt = 1;
|
||||
tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */
|
||||
|
||||
h = u8x8->display_info->tile_height;
|
||||
tile.y_pos = 0;
|
||||
do
|
||||
{
|
||||
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile);
|
||||
tile.y_pos++;
|
||||
} while( tile.y_pos < h );
|
||||
}
|
||||
|
||||
void u8x8_ClearDisplay(u8x8_t *u8x8)
|
||||
{
|
||||
uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
u8x8_ClearDisplayWithTile(u8x8, buf);
|
||||
}
|
||||
|
||||
void u8x8_FillDisplay(u8x8_t *u8x8)
|
||||
{
|
||||
uint8_t buf[8] = { 255, 255, 255, 255, 255, 255, 255, 255 };
|
||||
u8x8_ClearDisplayWithTile(u8x8, buf);
|
||||
}
|
||||
|
||||
void u8x8_ClearLine(u8x8_t *u8x8, uint8_t line)
|
||||
{
|
||||
uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
u8x8_tile_t tile;
|
||||
if ( line < u8x8->display_info->tile_height )
|
||||
{
|
||||
tile.x_pos = 0;
|
||||
tile.y_pos = line;
|
||||
tile.cnt = 1;
|
||||
tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */
|
||||
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
|
||||
u8x8_gpio.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
|
||||
void u8x8_gpio_call(u8x8_t *u8x8, uint8_t msg, uint8_t arg)
|
||||
{
|
||||
u8x8->gpio_and_delay_cb(u8x8, msg, arg, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
void u8x8_gpio_Delay(u8x8_t *u8x8, uint8_t msg, uint8_t dly)
|
||||
{
|
||||
u8x8->gpio_and_delay_cb(u8x8, msg, dly, NULL);
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
|
||||
u8x8_input_value.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
/*
|
||||
return:
|
||||
0: value is not changed (HOME/Break Button pressed)
|
||||
1: value has been updated
|
||||
*/
|
||||
|
||||
uint8_t u8x8_UserInterfaceInputValue(u8x8_t *u8x8, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post)
|
||||
{
|
||||
uint8_t height;
|
||||
uint8_t y;
|
||||
uint8_t width;
|
||||
uint8_t x;
|
||||
uint8_t local_value = *value;
|
||||
uint8_t r;
|
||||
uint8_t event;
|
||||
|
||||
/* calculate overall height of the input value box */
|
||||
height = 1; /* button line */
|
||||
height += u8x8_GetStringLineCnt(title);
|
||||
|
||||
/* calculate offset from top */
|
||||
y = 0;
|
||||
if ( height < u8x8_GetRows(u8x8) )
|
||||
{
|
||||
y = u8x8_GetRows(u8x8);
|
||||
y -= height;
|
||||
y /= 2;
|
||||
}
|
||||
|
||||
/* calculate offset from left for the label */
|
||||
x = 0;
|
||||
width = u8x8_GetUTF8Len(u8x8, pre);
|
||||
width += digits;
|
||||
width += u8x8_GetUTF8Len(u8x8, post);
|
||||
if ( width < u8x8_GetCols(u8x8) )
|
||||
{
|
||||
x = u8x8_GetCols(u8x8);
|
||||
x -= width;
|
||||
x /= 2;
|
||||
}
|
||||
|
||||
/* render */
|
||||
u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */
|
||||
u8x8_SetInverseFont(u8x8, 0);
|
||||
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title);
|
||||
x += u8x8_DrawUTF8(u8x8, x, y, pre);
|
||||
u8x8_DrawUTF8(u8x8, x+digits, y, post);
|
||||
u8x8_SetInverseFont(u8x8, 1);
|
||||
|
||||
/* event loop */
|
||||
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
|
||||
for(;;)
|
||||
{
|
||||
event = u8x8_GetMenuEvent(u8x8);
|
||||
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||
{
|
||||
*value = local_value;
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||
{
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP )
|
||||
{
|
||||
if ( local_value >= hi )
|
||||
local_value = lo;
|
||||
else
|
||||
local_value++;
|
||||
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
|
||||
}
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||
{
|
||||
if ( local_value <= lo )
|
||||
local_value = hi;
|
||||
else
|
||||
local_value--;
|
||||
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
|
||||
}
|
||||
}
|
||||
|
||||
u8x8_SetInverseFont(u8x8, 0);
|
||||
return r;
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
|
||||
u8x8_message.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
uint8_t u8x8_draw_button_line(u8x8_t *u8x8, uint8_t y, uint8_t w, uint8_t cursor, const char *s)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t cnt;
|
||||
uint8_t total;
|
||||
uint8_t d;
|
||||
uint8_t x;
|
||||
cnt = u8x8_GetStringLineCnt(s);
|
||||
|
||||
/* calculate the width of the button */
|
||||
total = 0;
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
total += u8x8_GetUTF8Len(u8x8, u8x8_GetStringLineStart(i, s));
|
||||
}
|
||||
total += (cnt-1); /* had one space between the buttons */
|
||||
|
||||
/* calculate the left offset */
|
||||
d = 0;
|
||||
if ( total < w )
|
||||
{
|
||||
d = w;
|
||||
d -= total;
|
||||
d /= 2;
|
||||
}
|
||||
|
||||
/* draw the buttons */
|
||||
x = d;
|
||||
u8x8_SetInverseFont(u8x8, 0);
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
if ( i == cursor )
|
||||
u8x8_SetInverseFont(u8x8, 1);
|
||||
|
||||
x+=u8x8_DrawUTF8(u8x8, x, y, u8x8_GetStringLineStart(i, s));
|
||||
u8x8_SetInverseFont(u8x8, 0);
|
||||
x+=u8x8_DrawUTF8(u8x8, x, y, " ");
|
||||
}
|
||||
|
||||
/* return the number of buttons */
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
title1: Multiple lines,separated by '\n'
|
||||
title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart()
|
||||
title3: Multiple lines,separated by '\n'
|
||||
buttons: one more more buttons separated by '\n' and terminated with '\0'
|
||||
*/
|
||||
|
||||
uint8_t u8x8_UserInterfaceMessage(u8x8_t *u8x8, const char *title1, const char *title2, const char *title3, const char *buttons)
|
||||
{
|
||||
uint8_t height;
|
||||
uint8_t y;
|
||||
uint8_t cursor = 0;
|
||||
uint8_t button_cnt;
|
||||
uint8_t event;
|
||||
|
||||
u8x8_SetInverseFont(u8x8, 0);
|
||||
|
||||
/* calculate overall height of the message box */
|
||||
height = 1; /* button line */
|
||||
height += u8x8_GetStringLineCnt(title1);
|
||||
if ( title2 != NULL )
|
||||
height ++;
|
||||
height += u8x8_GetStringLineCnt(title3);
|
||||
|
||||
/* calculate offset from top */
|
||||
y = 0;
|
||||
if ( height < u8x8_GetRows(u8x8) )
|
||||
{
|
||||
y = u8x8_GetRows(u8x8);
|
||||
y -= height;
|
||||
y /= 2;
|
||||
}
|
||||
|
||||
/* draw message box */
|
||||
|
||||
u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */
|
||||
|
||||
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title1);
|
||||
if ( title2 != NULL )
|
||||
{
|
||||
u8x8_DrawUTF8Line(u8x8, 0, y, u8x8_GetCols(u8x8), title2);
|
||||
y++;
|
||||
}
|
||||
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title3);
|
||||
|
||||
button_cnt = u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
event = u8x8_GetMenuEvent(u8x8);
|
||||
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||
return cursor+1;
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||
break;
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP )
|
||||
{
|
||||
cursor++;
|
||||
if ( cursor >= button_cnt )
|
||||
cursor = 0;
|
||||
u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
|
||||
}
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||
{
|
||||
if ( cursor == 0 )
|
||||
cursor = button_cnt;
|
||||
cursor--;
|
||||
u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
|
||||
u8x8_selection_list.c
|
||||
|
||||
selection list with scroll option
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
/*
|
||||
increase the cursor position
|
||||
*/
|
||||
void u8sl_Next(u8sl_t *u8sl)
|
||||
{
|
||||
u8sl->current_pos++;
|
||||
if ( u8sl->current_pos >= u8sl->total )
|
||||
{
|
||||
u8sl->current_pos = 0;
|
||||
u8sl->first_pos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( u8sl->first_pos + u8sl->visible <= u8sl->current_pos + 1 )
|
||||
{
|
||||
u8sl->first_pos = u8sl->current_pos - u8sl->visible + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void u8sl_Prev(u8sl_t *u8sl)
|
||||
{
|
||||
if ( u8sl->current_pos == 0 )
|
||||
{
|
||||
u8sl->current_pos = u8sl->total - 1;
|
||||
u8sl->first_pos = 0;
|
||||
if ( u8sl->total > u8sl->visible )
|
||||
u8sl->first_pos = u8sl->total - u8sl->visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
u8sl->current_pos--;
|
||||
if ( u8sl->first_pos > u8sl->current_pos )
|
||||
u8sl->first_pos = u8sl->current_pos;
|
||||
}
|
||||
}
|
||||
|
||||
void u8x8_DrawSelectionList(u8x8_t *u8x8, u8sl_t *u8sl, u8x8_sl_cb sl_cb, const void *aux)
|
||||
{
|
||||
uint8_t i;
|
||||
for( i = 0; i < u8sl->visible; i++ )
|
||||
{
|
||||
sl_cb(u8x8, u8sl, i+u8sl->first_pos, aux);
|
||||
}
|
||||
}
|
||||
|
||||
/* selection list with string line */
|
||||
void u8x8_sl_string_line_cb(u8x8_t *u8x8, u8sl_t *u8sl, uint8_t idx, const void *aux)
|
||||
{
|
||||
const char *s;
|
||||
uint8_t row;
|
||||
/* calculate offset from display upper border */
|
||||
row = u8sl->y;
|
||||
|
||||
/* calculate target pos */
|
||||
row += idx;
|
||||
row -= u8sl->first_pos;
|
||||
|
||||
/* check whether this is the current cursor line */
|
||||
if ( idx == u8sl->current_pos )
|
||||
u8x8_SetInverseFont(u8x8, 1);
|
||||
else
|
||||
u8x8_SetInverseFont(u8x8, 0);
|
||||
|
||||
/* get the line from the array */
|
||||
s = u8x8_GetStringLineStart(idx, (const char *)aux);
|
||||
|
||||
/* draw the line */
|
||||
if ( s == NULL )
|
||||
s = "";
|
||||
u8x8_DrawUTF8Line(u8x8, u8sl->x, row, u8x8_GetCols(u8x8), s);
|
||||
u8x8_SetInverseFont(u8x8, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n'
|
||||
start_pos: default position for the cursor (starts with 1)
|
||||
sl: string list (list of strings separated by \n)
|
||||
returns 0 if user has pressed the home key
|
||||
returns the selected line+1 if user has pressed the select key (e.g. 1 for the first line)
|
||||
*/
|
||||
uint8_t u8x8_UserInterfaceSelectionList(u8x8_t *u8x8, const char *title, uint8_t start_pos, const char *sl)
|
||||
{
|
||||
u8sl_t u8sl;
|
||||
uint8_t event;
|
||||
uint8_t title_lines;
|
||||
|
||||
if ( start_pos > 0 )
|
||||
start_pos--;
|
||||
|
||||
u8sl.visible = u8x8_GetRows(u8x8);
|
||||
u8sl.total = u8x8_GetStringLineCnt(sl);
|
||||
u8sl.first_pos = 0;
|
||||
u8sl.current_pos = start_pos;
|
||||
u8sl.x = 0;
|
||||
u8sl.y = 0;
|
||||
|
||||
|
||||
//u8x8_ClearDisplay(u8x8); /* not required because all is 100% filled */
|
||||
u8x8_SetInverseFont(u8x8, 0);
|
||||
|
||||
if ( title != NULL )
|
||||
{
|
||||
title_lines = u8x8_DrawUTF8Lines(u8x8, u8sl.x, u8sl.y, u8x8_GetCols(u8x8), title);
|
||||
u8sl.y+=title_lines;
|
||||
u8sl.visible-=title_lines;
|
||||
}
|
||||
|
||||
if ( u8sl.current_pos >= u8sl.total )
|
||||
u8sl.current_pos = u8sl.total-1;
|
||||
|
||||
|
||||
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
event = u8x8_GetMenuEvent(u8x8);
|
||||
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
|
||||
return u8sl.current_pos+1;
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
|
||||
return 0;
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN )
|
||||
{
|
||||
u8sl_Next(&u8sl);
|
||||
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
|
||||
}
|
||||
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP )
|
||||
{
|
||||
u8sl_Prev(&u8sl);
|
||||
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
|
||||
u8x8_setup.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
uint8_t u8x8_dummy_cb(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
|
||||
{
|
||||
/* the dummy callback will not handle any message and will fail for all messages */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Description:
|
||||
Setup u8x8
|
||||
Args:
|
||||
u8x8 An empty u8x8 structure
|
||||
*/
|
||||
void u8x8_SetupDefaults(u8x8_t *u8x8)
|
||||
{
|
||||
u8x8->display_info = NULL;
|
||||
u8x8->display_cb = u8x8_dummy_cb;
|
||||
u8x8->cad_cb = u8x8_dummy_cb;
|
||||
u8x8->byte_cb = u8x8_dummy_cb;
|
||||
u8x8->gpio_and_delay_cb = u8x8_dummy_cb;
|
||||
u8x8->is_font_inverse_mode = 0;
|
||||
u8x8->device_address = 0;
|
||||
u8x8->utf8_state = 0; /* also reset by u8x8_utf8_init */
|
||||
u8x8->i2c_address = 255;
|
||||
u8x8->debounce_default_pin_state = 255; /* assume all low active buttons */
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
{
|
||||
uint8_t i;
|
||||
for( i = 0; i < U8X8_PIN_CNT; i++ )
|
||||
u8x8->pins[i] = U8X8_PIN_NONE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Description:
|
||||
Setup u8x8 and assign the callback function. The dummy
|
||||
callback "u8x8_dummy_cb" can be used, if no callback is required.
|
||||
This setup will not communicate with the display itself.
|
||||
Use u8x8_InitDisplay() to send the startup code to the Display.
|
||||
Args:
|
||||
u8x8 An empty u8x8 structure
|
||||
display_cb Display/controller specific callback function
|
||||
cad_cb Display controller specific communication callback function
|
||||
byte_cb Display controller/communication specific callback funtion
|
||||
gpio_and_delay_cb Environment specific callback function
|
||||
|
||||
*/
|
||||
void u8x8_Setup(u8x8_t *u8x8, u8x8_msg_cb display_cb, u8x8_msg_cb cad_cb, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
|
||||
{
|
||||
/* setup defaults and reset pins to U8X8_PIN_NONE */
|
||||
u8x8_SetupDefaults(u8x8);
|
||||
|
||||
/* setup specific callbacks */
|
||||
u8x8->display_cb = display_cb;
|
||||
u8x8->cad_cb = cad_cb;
|
||||
u8x8->byte_cb = byte_cb;
|
||||
u8x8->gpio_and_delay_cb = gpio_and_delay_cb;
|
||||
|
||||
/* setup display info */
|
||||
u8x8_SetupMemory(u8x8);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
|
||||
u8x8_string.c
|
||||
|
||||
string line procedures
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
uint8_t u8x8_GetStringLineCnt(const char *str)
|
||||
{
|
||||
char e;
|
||||
uint8_t line_cnt = 1;
|
||||
if ( str == NULL )
|
||||
return 0;
|
||||
for(;;)
|
||||
{
|
||||
e = *str;
|
||||
if ( e == '\0' )
|
||||
break;
|
||||
str++;
|
||||
if ( e == '\n' )
|
||||
line_cnt++;
|
||||
}
|
||||
return line_cnt;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Assumes strings, separated by '\n' in "str".
|
||||
Returns the string at index "line_idx". First strng has line_idx = 0
|
||||
Example:
|
||||
Returns "xyz" for line_idx = 1 with str = "abc\nxyz"
|
||||
Support both UTF8 and normal strings.
|
||||
*/
|
||||
const char *u8x8_GetStringLineStart(uint8_t line_idx, const char *str )
|
||||
{
|
||||
char e;
|
||||
uint8_t line_cnt = 1;
|
||||
|
||||
if ( line_idx == 0 )
|
||||
return str;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
e = *str;
|
||||
if ( e == '\0' )
|
||||
break;
|
||||
str++;
|
||||
if ( e == '\n' )
|
||||
{
|
||||
if ( line_cnt == line_idx )
|
||||
return str;
|
||||
line_cnt++;
|
||||
}
|
||||
}
|
||||
return NULL; /* line not found */
|
||||
}
|
||||
|
||||
/* copy until first '\n' or '\0' in str */
|
||||
/* Important: There is no string overflow check, ensure */
|
||||
/* that the destination buffer is large enough */
|
||||
void u8x8_CopyStringLine(char *dest, uint8_t line_idx, const char *str)
|
||||
{
|
||||
if ( dest == NULL )
|
||||
return;
|
||||
str = u8x8_GetStringLineStart( line_idx, str );
|
||||
if ( str != NULL )
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if ( *str == '\n' || *str == '\0' )
|
||||
break;
|
||||
*dest = *str;
|
||||
dest++;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
Draw a string
|
||||
Extend the string to size "w"
|
||||
Center the string within "w"
|
||||
return the size of the string
|
||||
|
||||
*/
|
||||
uint8_t u8x8_DrawUTF8Line(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s)
|
||||
{
|
||||
uint8_t d, lw;
|
||||
uint8_t cx, dx;
|
||||
|
||||
d = 0;
|
||||
|
||||
lw = u8x8_GetUTF8Len(u8x8, s);
|
||||
if ( lw < w )
|
||||
{
|
||||
d = w;
|
||||
d -=lw;
|
||||
d /= 2;
|
||||
}
|
||||
|
||||
cx = x;
|
||||
dx = cx + d;
|
||||
while( cx < dx )
|
||||
{
|
||||
u8x8_DrawUTF8(u8x8, cx, y, " ");
|
||||
cx++;
|
||||
}
|
||||
cx += u8x8_DrawUTF8(u8x8, cx, y, s);
|
||||
dx = x + w;
|
||||
while( cx < dx )
|
||||
{
|
||||
u8x8_DrawUTF8(u8x8, cx, y, " ");
|
||||
cx++;
|
||||
}
|
||||
cx -= x;
|
||||
return cx;
|
||||
}
|
||||
|
||||
/*
|
||||
draw several lines at position x,y.
|
||||
lines are stored in s and must be separated with '\n'.
|
||||
lines can be centered with respect to "w"
|
||||
if s == NULL nothing is drawn and 0 is returned
|
||||
returns the number of lines in s
|
||||
*/
|
||||
uint8_t u8x8_DrawUTF8Lines(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t cnt;
|
||||
cnt = u8x8_GetStringLineCnt(s);
|
||||
for( i = 0; i < cnt; i++ )
|
||||
{
|
||||
u8x8_DrawUTF8Line(u8x8, x, y, w, u8x8_GetStringLineStart(i, s));
|
||||
y++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
|
||||
u8x8_u16toa.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
const char *u8x8_u16toap(char * dest, uint16_t v)
|
||||
{
|
||||
uint8_t pos;
|
||||
uint8_t d;
|
||||
uint16_t c;
|
||||
c = 10000;
|
||||
for( pos = 0; pos < 5; pos++ )
|
||||
{
|
||||
d = '0';
|
||||
while( v >= c )
|
||||
{
|
||||
v -= c;
|
||||
d++;
|
||||
}
|
||||
dest[pos] = d;
|
||||
c /= 10;
|
||||
}
|
||||
dest[5] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* v = value, d = number of digits */
|
||||
const char *u8x8_u16toa(uint16_t v, uint8_t d)
|
||||
{
|
||||
static char buf[6];
|
||||
d = 5-d;
|
||||
return u8x8_u16toap(buf, v) + d;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
|
||||
u8x8_u8toa.c
|
||||
|
||||
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
|
||||
|
||||
Copyright (c) 2016, 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 "u8x8.h"
|
||||
|
||||
static const unsigned char u8x8_u8toa_tab[3] = { 100, 10, 1 } ;
|
||||
const char *u8x8_u8toap(char * dest, uint8_t v)
|
||||
{
|
||||
uint8_t pos;
|
||||
uint8_t d;
|
||||
uint8_t c;
|
||||
for( pos = 0; pos < 3; pos++ )
|
||||
{
|
||||
d = '0';
|
||||
c = *(u8x8_u8toa_tab+pos);
|
||||
while( v >= c )
|
||||
{
|
||||
v -= c;
|
||||
d++;
|
||||
}
|
||||
dest[pos] = d;
|
||||
}
|
||||
dest[3] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* v = value, d = number of digits */
|
||||
const char *u8x8_u8toa(uint8_t v, uint8_t d)
|
||||
{
|
||||
static char buf[4];
|
||||
d = 3-d;
|
||||
return u8x8_u8toap(buf, v) + d;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
u8x8cb.c
|
||||
|
||||
STM32L031
|
||||
|
||||
PA13: Clock
|
||||
PA14: Data
|
||||
Both lines have a pullup resistor
|
||||
|
||||
*/
|
||||
|
||||
#include "stm32l031xx.h"
|
||||
#include "delay.h"
|
||||
#include "u8x8.h"
|
||||
|
||||
|
||||
uint8_t u8x8_gpio_and_delay_stm32l0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_GPIO_AND_DELAY_INIT:
|
||||
/* only support for software I2C*/
|
||||
|
||||
RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
|
||||
__NOP();
|
||||
__NOP();
|
||||
|
||||
GPIOA->MODER &= ~GPIO_MODER_MODE14; /* clear mode for PA10 */
|
||||
//GPIOA->MODER |= GPIO_MODER_MODE14_0; /* Output mode for PA10 */
|
||||
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_14; /* no open drain for PA10 */
|
||||
GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED14; /* low speed for PA10 */
|
||||
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD14; /* no pullup/pulldown for PA10 */
|
||||
//GPIOA->BSRR = GPIO_BSRR_BS_14; /* atomic set PA10 */
|
||||
|
||||
GPIOA->MODER &= ~GPIO_MODER_MODE13; /* clear mode for PA9 */
|
||||
//GPIOA->MODER |= GPIO_MODER_MODE13_0; /* Output mode for PA9 */
|
||||
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_13; /* no open drain for PA9 */
|
||||
GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEED13; /* low speed for PA9 */
|
||||
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPD13; /* no pullup/pulldown for PA9 */
|
||||
//GPIOA->BSRR = GPIO_BSRR_BS_13; /* atomic set PA9 */
|
||||
|
||||
break;
|
||||
case U8X8_MSG_DELAY_NANO:
|
||||
/* not required for SW I2C */
|
||||
break;
|
||||
|
||||
case U8X8_MSG_DELAY_10MICRO:
|
||||
/* not used at the moment */
|
||||
break;
|
||||
|
||||
case U8X8_MSG_DELAY_100NANO:
|
||||
/* not used at the moment */
|
||||
break;
|
||||
|
||||
case U8X8_MSG_DELAY_MILLI:
|
||||
delay_micro_seconds(arg_int*1000UL);
|
||||
break;
|
||||
case U8X8_MSG_DELAY_I2C:
|
||||
/* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
|
||||
delay_micro_seconds(arg_int<=2?5:1);
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_I2C_CLOCK:
|
||||
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
GPIOA->MODER &= ~GPIO_MODER_MODE13; /* clear mode for PA10 */
|
||||
GPIOA->MODER |= GPIO_MODER_MODE13_0; /* Output mode for PA10 */
|
||||
GPIOA->BSRR = GPIO_BSRR_BR_3; /* atomic clr PA9 */
|
||||
}
|
||||
else
|
||||
{
|
||||
//GPIOA->BSRR = GPIO_BSRR_BS_13; /* atomic set PA9 */
|
||||
GPIOA->MODER &= ~GPIO_MODER_MODE13; /* clear mode for PA9: input mode */
|
||||
}
|
||||
break;
|
||||
case U8X8_MSG_GPIO_I2C_DATA:
|
||||
|
||||
if ( arg_int == 0 )
|
||||
{
|
||||
GPIOA->MODER &= ~GPIO_MODER_MODE14; /* clear mode for PA10 */
|
||||
GPIOA->MODER |= GPIO_MODER_MODE14_0; /* Output mode for PA10 */
|
||||
GPIOA->BSRR = GPIO_BSRR_BR_14; /* atomic clr PA10 */
|
||||
}
|
||||
else
|
||||
{
|
||||
//GPIOA->BSRR = GPIO_BSRR_BS_14; /* atomic set PA10 */
|
||||
// input mode
|
||||
GPIOA->MODER &= ~GPIO_MODER_MODE14; /* clear mode for PA10: input mode */
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case U8X8_MSG_GPIO_MENU_SELECT:
|
||||
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_SELECT_PORT, KEY_SELECT_PIN));
|
||||
break;
|
||||
case U8X8_MSG_GPIO_MENU_NEXT:
|
||||
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_NEXT_PORT, KEY_NEXT_PIN));
|
||||
break;
|
||||
case U8X8_MSG_GPIO_MENU_PREV:
|
||||
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_PREV_PORT, KEY_PREV_PIN));
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_MENU_HOME:
|
||||
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_HOME_PORT, KEY_HOME_PIN));
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
u8x8_SetGPIOResult(u8x8, 1);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user