From 41fa8da2b4892fbff7d78601412b42893288b7b9 Mon Sep 17 00:00:00 2001 From: olikraus Date: Tue, 22 Dec 2015 22:23:42 +0100 Subject: [PATCH] u8g2 c++ --- cppsrc/U8g2lib.h | 61 +++- cppsrc/U8x8lib.h | 3 - csrc/u8g2.h | 20 ++ csrc/u8g2_d_memory.c | 42 +++ csrc/u8g2_d_setup.c | 62 ++++ .../HelloWorldPageBuffer.ino | 22 ++ .../Makefile.105.uno | 284 ++++++++++++++++++ .../u8x8_GraphicsTest/GraphicsTest.ino | 4 +- tools/codebuild/codebuild.c | 113 ++++++- 9 files changed, 594 insertions(+), 17 deletions(-) create mode 100644 csrc/u8g2_d_memory.c create mode 100644 csrc/u8g2_d_setup.c create mode 100644 sys/arduino/u8g2_HelloWorldPageBuffer/HelloWorldPageBuffer.ino create mode 100644 sys/arduino/u8g2_HelloWorldPageBuffer/Makefile.105.uno diff --git a/cppsrc/U8g2lib.h b/cppsrc/U8g2lib.h index 6b55811e..4a97b014 100644 --- a/cppsrc/U8g2lib.h +++ b/cppsrc/U8g2lib.h @@ -25,7 +25,7 @@ class U8G2 : public Print protected: u8g2_t u8g2; public: - uint8_t tx, ty; + u8g2_uint_t tx, ty; U8G2(void) { home(); } u8x8_t *getU8x8(void) { return u8g2_GetU8x8(&u8g2); } @@ -34,11 +34,66 @@ class U8G2 : public Print /* u8x8 interface */ uint8_t getCols(void) { return u8x8_GetCols(u8g2_GetU8x8(&u8g2)); } uint8_t getRows(void) { return u8x8_GetRows(u8g2_GetU8x8(&u8g2)); } + + void initDisplay(void) { + u8g2_InitDisplay(&u8g2); } + + void clearScreen(void) { + u8g2_ClearDisplay(&u8g2); } + + void setPowerSave(uint8_t is_enable) { + u8g2_SetPowerSave(&u8g2, is_enable); } + void begin(void) { + initDisplay(); clearScreen(); setPowerSave(0); } + /* u8g2 */ + void firstPage(void) { u8g2_FirstPage(&u8g2); } + uint8_t nextPage(void) { return u8g2_NextPage(&u8g2); } + + void setFont(const uint8_t *font) {u8g2_SetFont(&u8g2, font); } + + u8g2_uint_t drawStr(u8g2_uint_t x, u8g2_uint_t y, const char *s) { return u8g2_DrawString(&u8g2, x, y, s); } + + size_t write(uint8_t v) { + tx += u8g2_DrawGlyph(&u8g2, tx, ty, v); + return 1; + } + + /* LiquidCrystal compatible functions */ + void home(void) { tx = 0; ty = 0; } + void clear(void) { clearScreen(); home(); } + void noDisplay(void) { u8g2_SetPowerSave(&u8g2, 1); } + void display(void) { u8g2_SetPowerSave(&u8g2, 0); } + void setCursor(uint8_t x, uint8_t y) { tx = x; ty = y; } + +}; + +/* + U8G2____ + memory + "1" one page + "2" two pages + "f" full frame buffer + communication + "SW SPI" + +*/ + + +class U8G2_SSD1306_128x64_NONAME_1_SW_SPI : public U8G2 +{ + public: + U8G2_SSD1306_128x64_NONAME_1_SW_SPI(const u8g2_cb_t *rotation, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset) + { + u8g2_Setup_ssd1306_128x64_noname_1(&u8g2, u8x8_byte_4wire_sw_spi, u8x8_gpio_and_delay_arduino, rotation); + u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_SPI_CLOCK, clock); + u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_SPI_DATA, data); + u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_CS, cs); + u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_DC, dc); + u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_RESET, reset); + } }; - - #endif /* _U8G2LIB_HH */ \ No newline at end of file diff --git a/cppsrc/U8x8lib.h b/cppsrc/U8x8lib.h index 41227a97..eafcd35e 100644 --- a/cppsrc/U8x8lib.h +++ b/cppsrc/U8x8lib.h @@ -92,9 +92,6 @@ class U8X8 : public Print void display(void) { u8x8_SetPowerSave(&u8x8, 0); } void setCursor(uint8_t x, uint8_t y) { tx = x; ty = y; } - void noCursor(void) {} - void cursor(void) {} - }; // constructor list start diff --git a/csrc/u8g2.h b/csrc/u8g2.h index 1b1016e0..8b9ae430 100644 --- a/csrc/u8g2.h +++ b/csrc/u8g2.h @@ -270,7 +270,27 @@ extern const u8g2_cb_t u8g2_cb_r3; void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, const u8g2_cb_t *u8g2_cb); +/*==========================================*/ +/* u8g2_d_memory.c generated code start */ +uint8_t *u8g2_m_ssd1306_16_1(uint8_t *page_cnt); +uint8_t *u8g2_m_ssd1306_16_2(uint8_t *page_cnt); +uint8_t *u8g2_m_ssd1306_16_f(uint8_t *page_cnt); +uint8_t *u8g2_m_uc1701_13_1(uint8_t *page_cnt); +uint8_t *u8g2_m_uc1701_13_2(uint8_t *page_cnt); +uint8_t *u8g2_m_uc1701_13_f(uint8_t *page_cnt); +/* u8g2_d_memory.c generated code end */ + +/*==========================================*/ +/* u8g2_d_setup.c generated code start */ +void u8g2_Setup_ssd1306_128x64_noname_1(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation); +void u8g2_Setup_ssd1306_128x64_noname_2(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation); +void u8g2_Setup_ssd1306_128x64_noname_f(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation); +void u8g2_Setup_uc1701_dogs102_1(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation); +void u8g2_Setup_uc1701_dogs102_2(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation); +void u8g2_Setup_uc1701_dogs102_f(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation); + +/* u8g2_d_setup.c generated code end */ /*==========================================*/ /* u8g2_buffer.c */ diff --git a/csrc/u8g2_d_memory.c b/csrc/u8g2_d_memory.c new file mode 100644 index 00000000..664a088f --- /dev/null +++ b/csrc/u8g2_d_memory.c @@ -0,0 +1,42 @@ +/* u8g2_d_memory.c */ +/* generated code, codebuild, u8g2 project */ + +#include "u8g2.h" + +uint8_t *u8g2_m_ssd1306_16_1(uint8_t *page_cnt) +{ + static uint8_t buf[128]; + *page_cnt = 1; + return buf; +} +uint8_t *u8g2_m_ssd1306_16_2(uint8_t *page_cnt) +{ + static uint8_t buf[256]; + *page_cnt = 2; + return buf; +} +uint8_t *u8g2_m_ssd1306_16_f(uint8_t *page_cnt) +{ + static uint8_t buf[1024]; + *page_cnt = 8; + return buf; +} +uint8_t *u8g2_m_uc1701_13_1(uint8_t *page_cnt) +{ + static uint8_t buf[104]; + *page_cnt = 1; + return buf; +} +uint8_t *u8g2_m_uc1701_13_2(uint8_t *page_cnt) +{ + static uint8_t buf[208]; + *page_cnt = 2; + return buf; +} +uint8_t *u8g2_m_uc1701_13_f(uint8_t *page_cnt) +{ + static uint8_t buf[832]; + *page_cnt = 8; + return buf; +} +/* end of generated code */ diff --git a/csrc/u8g2_d_setup.c b/csrc/u8g2_d_setup.c new file mode 100644 index 00000000..0afdb545 --- /dev/null +++ b/csrc/u8g2_d_setup.c @@ -0,0 +1,62 @@ +/* u8g2_d_setup.c */ +/* generated code, codebuild, u8g2 project */ + +#include "u8g2.h" + +/* ssd1306 */ +/* ssd1306 1 */ +void u8g2_Setup_ssd1306_128x64_noname_1(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_ssd1306_16_1(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, rotation); +} +/* ssd1306 2 */ +void u8g2_Setup_ssd1306_128x64_noname_2(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_ssd1306_16_2(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, rotation); +} +/* ssd1306 f */ +void u8g2_Setup_ssd1306_128x64_noname_f(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_ssd1306_16_f(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, rotation); +} +/* uc1701 */ +/* uc1701 1 */ +void u8g2_Setup_uc1701_dogs102_1(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_uc1701_dogs102, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_uc1701_13_1(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, rotation); +} +/* uc1701 2 */ +void u8g2_Setup_uc1701_dogs102_2(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_uc1701_dogs102, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_uc1701_13_2(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, rotation); +} +/* uc1701 f */ +void u8g2_Setup_uc1701_dogs102_f(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation) +{ + uint8_t tile_buf_height; + uint8_t *buf; + u8g2_SetupDisplay(u8g2, u8x8_d_uc1701_dogs102, u8x8_cad_001, byte_cb, gpio_and_delay_cb); + buf = u8g2_m_uc1701_13_f(&tile_buf_height); + u8g2_SetupBuffer(u8g2, buf, tile_buf_height, rotation); +} +/* end of generated code */ diff --git a/sys/arduino/u8g2_HelloWorldPageBuffer/HelloWorldPageBuffer.ino b/sys/arduino/u8g2_HelloWorldPageBuffer/HelloWorldPageBuffer.ino new file mode 100644 index 00000000..0148cb38 --- /dev/null +++ b/sys/arduino/u8g2_HelloWorldPageBuffer/HelloWorldPageBuffer.ino @@ -0,0 +1,22 @@ +#include +#include + +#include + +U8G2_SSD1306_128x64_NONAME_1_SW_SPI u8g2(&u8g2_cb_r0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); + + + +void setup(void) { + u8g2.begin(); +} + +void loop(void) { + u8g2.firstPage(); + do { + u8g2.setFont(u8g2_font_ncenB14_tr); + u8g2.drawStr(0,20,"Hello World!"); + } while ( u8g2.nextPage() ); + delay(1000); +} + diff --git a/sys/arduino/u8g2_HelloWorldPageBuffer/Makefile.105.uno b/sys/arduino/u8g2_HelloWorldPageBuffer/Makefile.105.uno new file mode 100644 index 00000000..9284f0ec --- /dev/null +++ b/sys/arduino/u8g2_HelloWorldPageBuffer/Makefile.105.uno @@ -0,0 +1,284 @@ + +# +# Arduino-1.0 Makefile +# +# written by olikraus@gmail.com +# +# Features: +# - boards.txt is used to derive parameters +# - All intermediate files are put into a separate directory (TMPDIRNAME) +# - Simple use: Copy Makefile into the same directory of the .ino file +# +# Limitations: +# - requires UNIX environment +# - TMPDIRNAME must be subdirectory of the current directory. +# +# Targets +# all build everything +# upload build and upload to arduino +# clean remove all temporary files (includes final hex file) +# +# History +# 001 28 Apr 2010 first release +# 002 05 Oct 2010 added 'uno' +# 003 06 Dec 2011 arduino 1.0 +# 004 11 Feb 2012 u8glib +# + +#=== user configuration === +# All ...PATH variables must have a '/' at the end + +# Board (and prozessor) information: see $(ARDUINO_PATH)hardware/arduino/boards.txt +# Some examples: +# BOARD DESCRIPTION +# uno Arduino Uno +# atmega328 Arduino Duemilanove or Nano w/ ATmega328 +# diecimila Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 +# mega Arduino Mega +# mega2560 Arduino Mega2560 +# mini Arduino Mini +# lilypad328 LilyPad Arduino w/ ATmega328 +BOARD:=uno + +# additional definitions +#DEFS:=-DARDUINO=105 + + +U8G_PATH:=$(shell cd ../../.. && pwd)/csrc/ +U8G_CPP_PATH:=$(shell cd ../../.. && pwd)/cppsrc/ +#U8G_FONT_PATH:=$(shell cd ../../.. && pwd)/sfntsrc/ + + +# The location where the avr tools (e.g. avr-gcc) are located. Requires a '/' at the end. +# Can be empty if all tools are accessable through the search path +AVR_TOOLS_PATH:=/usr/bin/ + +# Install path of the arduino software. Requires a '/' at the end. +ARDUINO_PATH:=/home/kraus/prg/arduino-1.0.5-u8glib/ + +# Install path for avrdude. Requires a '/' at the end. Can be empty if avrdude is in the search path. +AVRDUDE_PATH:=$(ARDUINO_PATH)hardware/tools/ + +# The unix device where we can reach the arduino board +# Uno: /dev/ttyACM0 +# Duemilanove: /dev/ttyUSB0 +AVRDUDE_PORT:=/dev/ttyACM0 + +# List of all libaries which should be included. +EXTRA_DIRS=$(ARDUINO_PATH)libraries/LiquidCrystal/ +EXTRA_DIRS+=$(ARDUINO_PATH)libraries/SD/ +EXTRA_DIRS+=$(ARDUINO_PATH)libraries/SD/utility/ +EXTRA_DIRS+=$(ARDUINO_PATH)libraries/SPI/ +#EXTRA_DIRS+=$(ARDUINO_PATH)libraries/.../ + +#=== fetch parameter from boards.txt processor parameter === +# the basic idea is to get most of the information from boards.txt + +BOARDS_TXT:=$(ARDUINO_PATH)hardware/arduino/boards.txt + +# get the MCU value from the $(BOARD).build.mcu variable. For the atmega328 board this is atmega328p +MCU:=$(shell sed -n -e "s/$(BOARD).build.mcu=\(.*\)/\1/p" $(BOARDS_TXT)) +# get the F_CPU value from the $(BOARD).build.f_cpu variable. For the atmega328 board this is 16000000 +F_CPU:=$(shell sed -n -e "s/$(BOARD).build.f_cpu=\(.*\)/\1/p" $(BOARDS_TXT)) +# get variant subfolder +VARIANT:=$(shell sed -n -e "s/$(BOARD).build.variant=\(.*\)/\1/p" $(BOARDS_TXT)) + + +# avrdude +# get the AVRDUDE_UPLOAD_RATE value from the $(BOARD).upload.speed variable. For the atmega328 board this is 57600 +AVRDUDE_UPLOAD_RATE:=$(shell sed -n -e "s/$(BOARD).upload.speed=\(.*\)/\1/p" $(BOARDS_TXT)) +# get the AVRDUDE_PROGRAMMER value from the $(BOARD).upload.protocol variable. For the atmega328 board this is stk500 +AVRDUDE_PROGRAMMER:=$(shell sed -n -e "s/$(BOARD).upload.protocol=\(.*\)/\1/p" $(BOARDS_TXT)) +# use stk500v1, because stk500 will default to stk500v2 +#AVRDUDE_PROGRAMMER:=stk500v1 + +#=== identify user files === +INOSRC:=$(shell ls *.ino) +TARGETNAME=$(basename $(INOSRC)) + +CDIRS:=$(EXTRA_DIRS) $(addsuffix utility/,$(EXTRA_DIRS)) +CDIRS:=*.c utility/*.c $(U8G_PATH)*.c $(addsuffix *.c,$(CDIRS)) $(ARDUINO_PATH)hardware/arduino/cores/arduino/*.c +CSRC:=$(shell ls $(CDIRS) 2>/dev/null) + +CCSRC:=$(shell ls *.cc 2>/dev/null) + +CPPDIRS:=$(EXTRA_DIRS) $(addsuffix utility/,$(EXTRA_DIRS)) $(U8G_CPP_PATH) +CPPDIRS:=*.cpp utility/*.cpp $(addsuffix *.cpp,$(CPPDIRS)) $(ARDUINO_PATH)hardware/arduino/cores/arduino/*.cpp +CPPSRC:=$(shell ls $(CPPDIRS) 2>/dev/null) + +#=== build internal variables === + +# the name of the subdirectory where everything is stored +TMPDIRNAME:=tmp +TMPDIRPATH:=$(TMPDIRNAME)/ + +AVRTOOLSPATH:=$(AVR_TOOLS_PATH) + +OBJCOPY:=$(AVRTOOLSPATH)avr-objcopy +OBJDUMP:=$(AVRTOOLSPATH)avr-objdump +SIZE:=$(AVRTOOLSPATH)avr-size + +CPPSRC:=$(addprefix $(TMPDIRPATH),$(INOSRC:.ino=.cpp)) $(CPPSRC) + +COBJ:=$(CSRC:.c=.o) +CCOBJ:=$(CCSRC:.cc=.o) +CPPOBJ:=$(CPPSRC:.cpp=.o) + +OBJFILES:=$(COBJ) $(CCOBJ) $(CPPOBJ) +DIRS:= $(dir $(OBJFILES)) + +DEPFILES:=$(OBJFILES:.o=.d) +# assembler files from avr-gcc -S +ASSFILES:=$(OBJFILES:.o=.s) +# disassembled object files with avr-objdump -S +DISFILES:=$(OBJFILES:.o=.dis) + + +LIBNAME:=$(TMPDIRPATH)$(TARGETNAME).a +ELFNAME:=$(TMPDIRPATH)$(TARGETNAME).elf +HEXNAME:=$(TMPDIRPATH)$(TARGETNAME).hex + +AVRDUDE_FLAGS = -V -F +AVRDUDE_FLAGS += -C $(ARDUINO_PATH)/hardware/tools/avrdude.conf +AVRDUDE_FLAGS += -p $(MCU) +AVRDUDE_FLAGS += -P $(AVRDUDE_PORT) +AVRDUDE_FLAGS += -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS += -b $(AVRDUDE_UPLOAD_RATE) +AVRDUDE_FLAGS += -U flash:w:$(HEXNAME) + +AVRDUDE = $(AVRDUDE_PATH)avrdude + +#=== predefined variable override === +# use "make -p -f/dev/null" to see the default rules and definitions + +# Build C and C++ flags. Include path information must be placed here +COMMON_FLAGS = -DF_CPU=$(F_CPU) -mmcu=$(MCU) $(DEFS) -DARDUINO=100 +# COMMON_FLAGS += -gdwarf-2 +COMMON_FLAGS += -Os +COMMON_FLAGS += -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +COMMON_FLAGS += -I$(ARDUINO_PATH)hardware/arduino/cores/arduino +COMMON_FLAGS += -I$(ARDUINO_PATH)hardware/arduino/variants/$(VARIANT) +COMMON_FLAGS += -I. -I$(U8G_PATH) -I$(U8G_CPP_PATH) +COMMON_FLAGS += $(addprefix -I,$(EXTRA_DIRS)) +COMMON_FLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections +COMMON_FLAGS += -Wl,--Map=output.map +COMMON_FLAGS += -Wl,--relax +COMMON_FLAGS += -mcall-prologues + +CFLAGS = $(COMMON_FLAGS) -std=gnu99 -Wstrict-prototypes +CXXFLAGS = $(COMMON_FLAGS) + +# Replace standard build tools by avr tools +CC = $(AVRTOOLSPATH)avr-gcc +CXX = $(AVRTOOLSPATH)avr-g++ +AR = @$(AVRTOOLSPATH)avr-ar + + +# "rm" must be able to delete a directory tree +RM = rm -rf + +#=== rules === + +# add rules for the C/C++ files where the .o file is placed in the TMPDIRPATH +# reuse existing variables as far as possible + +$(TMPDIRPATH)%.o: %.c + @echo compile $< + @$(COMPILE.c) $(OUTPUT_OPTION) $< + +$(TMPDIRPATH)%.o: %.cc + @echo compile $< + @$(COMPILE.cc) $(OUTPUT_OPTION) $< + +$(TMPDIRPATH)%.o: %.cpp + @echo compile $< + @$(COMPILE.cpp) $(OUTPUT_OPTION) $< + +$(TMPDIRPATH)%.s: %.c + @$(COMPILE.c) $(OUTPUT_OPTION) -S $< + +$(TMPDIRPATH)%.s: %.cc + @$(COMPILE.cc) $(OUTPUT_OPTION) -S $< + +$(TMPDIRPATH)%.s: %.cpp + @$(COMPILE.cpp) $(OUTPUT_OPTION) -S $< + +$(TMPDIRPATH)%.dis: $(TMPDIRPATH)%.o + @$(OBJDUMP) -S $< > $@ + +.SUFFIXES: .elf .hex .ino + +.elf.hex: + @$(OBJCOPY) -O ihex -R .eeprom $< $@ + +$(TMPDIRPATH)%.cpp: %.ino + @cat $(ARDUINO_PATH)hardware/arduino/cores/arduino/main.cpp > $@ + @cat $< >> $@ + @echo >> $@ + @echo 'extern "C" void __cxa_pure_virtual() { while (1); }' >> $@ + + +.PHONY: all +all: tmpdir $(HEXNAME) assemblersource showsize + ls -al $(HEXNAME) $(ELFNAME) + +$(ELFNAME): $(LIBNAME)($(addprefix $(TMPDIRPATH),$(OBJFILES))) + $(LINK.o) $(COMMON_FLAGS) $(LIBNAME) $(LOADLIBES) $(LDLIBS) -o $@ + +$(LIBNAME)(): $(addprefix $(TMPDIRPATH),$(OBJFILES)) + +#=== create temp directory === +# not really required, because it will be also created during the dependency handling +.PHONY: tmpdir +tmpdir: + @test -d $(TMPDIRPATH) || mkdir $(TMPDIRPATH) + +#=== create assembler files for each C/C++ file === +.PHONY: assemblersource +assemblersource: $(addprefix $(TMPDIRPATH),$(ASSFILES)) $(addprefix $(TMPDIRPATH),$(DISFILES)) + + +#=== show the section sizes of the ELF file === +.PHONY: showsize +showsize: $(ELFNAME) + $(SIZE) $< + +#=== clean up target === +# this is simple: the TMPDIRPATH is removed +.PHONY: clean +clean: + $(RM) $(TMPDIRPATH) + +# Program the device. +# step 1: reset the arduino board with the stty command +# step 2: user avrdude to upload the software +.PHONY: upload +upload: $(HEXNAME) + stty -F $(AVRDUDE_PORT) hupcl + $(AVRDUDE) $(AVRDUDE_FLAGS) + + +# === dependency handling === +# From the gnu make manual (section 4.14, Generating Prerequisites Automatically) +# Additionally (because this will be the first executed rule) TMPDIRPATH is created here. +# Instead of "sed" the "echo" command is used +# cd $(TMPDIRPATH); mkdir -p $(DIRS) 2> /dev/null; cd .. +DEPACTION=test -d $(TMPDIRPATH) || mkdir $(TMPDIRPATH);\ +mkdir -p $(addprefix $(TMPDIRPATH),$(DIRS));\ +set -e; echo -n $@ $(dir $@) > $@; $(CC) -MM $(COMMON_FLAGS) $< >> $@ + + +$(TMPDIRPATH)%.d: %.c + @$(DEPACTION) + +$(TMPDIRPATH)%.d: %.cc + @$(DEPACTION) + +$(TMPDIRPATH)%.d: %.cpp + @$(DEPACTION) + +# Include dependency files. If a .d file is missing, a warning is created and the .d file is created +# This warning is not a problem (gnu make manual, section 3.3 Including Other Makefiles) +-include $(addprefix $(TMPDIRPATH),$(DEPFILES)) + + diff --git a/sys/arduino/u8x8_GraphicsTest/GraphicsTest.ino b/sys/arduino/u8x8_GraphicsTest/GraphicsTest.ino index a4341763..657c7c8c 100644 --- a/sys/arduino/u8x8_GraphicsTest/GraphicsTest.ino +++ b/sys/arduino/u8x8_GraphicsTest/GraphicsTest.ino @@ -3,8 +3,8 @@ #include -//U8X8_SSD1306_128X64_4W_SW_SPI u8x8(/* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); -U8X8_SSD1306_128X64_4W_HW_SPI u8x8(/* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); +U8X8_SSD1306_128X64_4W_SW_SPI u8x8(/* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); +//U8X8_SSD1306_128X64_4W_HW_SPI u8x8(/* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8X8_SSD1306_128X64_3W_SW_SPI u8x8(/* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* reset=*/ 8); //U8X8_SSD1306_128X64_6800 u8x8(13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); //U8X8_SSD1306_128X64_8080 u8x8(13, 11, 2, 3, 4, 5, 6, A4, /*enable=*/ 7, /*cs=*/ 10, /*dc=*/ 9, /*reset=*/ 8); diff --git a/tools/codebuild/codebuild.c b/tools/codebuild/codebuild.c index 6b4459b7..98e4669f 100644 --- a/tools/codebuild/codebuild.c +++ b/tools/codebuild/codebuild.c @@ -37,6 +37,95 @@ struct controller controller_list[] = } }; + +/*===========================================*/ + +/* + copy file from source_file_name to dest_file_name +*/ +int file_copy(const char *source_file_name, const char *dest_file_name) +{ + int ch; + FILE *source_fp; + FILE *dest_fp; + + source_fp = fopen(source_file_name, "r"); + dest_fp = fopen(dest_file_name, "w"); + + if ( source_fp == NULL || dest_fp == NULL ) + return 0; + + while( ( ch = fgetc(source_fp) ) != EOF ) + fputc(ch, dest_fp); + + fclose(source_fp); + fclose(dest_fp); + + return 1; +} + + +/* + Insert file "insertname" between lines "start_line" and "end_line" of file "filename" +*/ +int insert_into_file(const char *filename, const char *insertname, const char *start_line, const char *end_line) +{ + int ch; + static char line[1024*4]; + const char *tmpname = "tmp.h"; + FILE *source_fp; + FILE *dest_fp; + FILE *insert_fp; + + if ( file_copy(filename, tmpname) == 0 ) + return 0; + + source_fp = fopen(tmpname, "r"); + dest_fp = fopen(filename, "w"); + insert_fp = fopen(insertname, "r"); + + if ( source_fp == NULL || dest_fp == NULL || insert_fp == NULL ) + return 0; + + for(;;) + { + if ( fgets(line, 1024*4, source_fp) == NULL ) + break; + if ( strncmp(line, start_line, strlen(start_line)) == 0 ) + { + fputs(line, dest_fp); + + while( ( ch = fgetc(insert_fp) ) != EOF ) + fputc(ch, dest_fp); + + fputs("\n", dest_fp); + + for(;;) + { + if ( fgets(line, 1024*4, source_fp) == NULL ) + break; + if ( strncmp(line, end_line, strlen(end_line)) == 0 ) + { + fputs(line, dest_fp); + break; + } + } + } + else + { + fputs(line, dest_fp); + } + } + + fclose(insert_fp); + fclose(source_fp); + fclose(dest_fp); + + unlink(tmpname); + + return 1; +} + /*===========================================*/ char *strlowercase(const char *s) @@ -67,10 +156,10 @@ FILE *setup_header_fp; void do_setup_prototype(FILE *fp, int controller_idx, int display_idx, const char *postfix) { - fprintf(fp, "uint8_t *u8g2_Setup_"); + fprintf(fp, "void u8g2_Setup_"); fprintf(fp, "%s_", strlowercase(controller_list[controller_idx].name)); fprintf(fp, "%s_", strlowercase(controller_list[controller_idx].display_list[display_idx].name)); - fprintf(fp, "%s(uint8_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation)", postfix); + fprintf(fp, "%s(u8g2_t *u8g2, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb, const u8g2_cb_t *rotation)", postfix); } /*===========================================*/ @@ -84,13 +173,13 @@ void do_display(int controller_idx, int display_idx, const char *postfix) fprintf(setup_code_fp, "\n"); fprintf(setup_code_fp, "{\n"); fprintf(setup_code_fp, " uint8_t tile_buf_height;\n"); - fprintf(setup_code_fp, " uint8_t *buffer;\n"); - fprintf(setup_code_fp, " u8g2_SetupDisplay(u8x8_d_"); + fprintf(setup_code_fp, " uint8_t *buf;\n"); + fprintf(setup_code_fp, " u8g2_SetupDisplay(u8g2, u8x8_d_"); fprintf(setup_code_fp, "%s_", strlowercase(controller_list[controller_idx].name)); fprintf(setup_code_fp, "%s, ", strlowercase(controller_list[controller_idx].display_list[display_idx].name)); fprintf(setup_code_fp, "%s, ", controller_list[controller_idx].cad); fprintf(setup_code_fp, "byte_cb, gpio_and_delay_cb);\n"); - fprintf(setup_code_fp, " buffer = "); + fprintf(setup_code_fp, " buf = "); fprintf(setup_code_fp, "u8g2_m_%s_%d_%s(&tile_buf_height);\n", strlowercase(controller_list[controller_idx].name), controller_list[controller_idx].tile_width, postfix); fprintf(setup_code_fp, " u8g2_SetupBuffer(u8g2, buf, tile_buf_height, rotation);\n"); fprintf(setup_code_fp, "}\n"); @@ -146,7 +235,7 @@ int main(void) fprintf(buf_code_fp, "\n"); buf_header_fp = fopen("u8g2_memory.h", "w"); - fprintf(buf_header_fp, "/* start of generated code, codebuild, u8g2 project */\n"); + //fprintf(buf_header_fp, "/* start of generated code, codebuild, u8g2 project */\n"); setup_code_fp = fopen("u8g2_d_setup.c", "w"); fprintf(setup_code_fp, "/* u8g2_d_setup.c */\n"); @@ -156,22 +245,28 @@ int main(void) fprintf(setup_code_fp, "\n"); setup_header_fp = fopen("u8g2_setup.h", "w"); - fprintf(setup_header_fp, "/* start of generated code, codebuild, u8g2 project */\n"); + //fprintf(setup_header_fp, "/* start of generated code, codebuild, u8g2 project */\n"); do_controller_list(); fprintf(buf_code_fp, "/* end of generated code */\n"); fclose(buf_code_fp); - fprintf(buf_header_fp, "/* end of generated code */\n"); + //fprintf(buf_header_fp, "/* end of generated code */\n"); fclose(buf_header_fp); fprintf(setup_code_fp, "/* end of generated code */\n"); fclose(setup_code_fp); - fprintf(setup_header_fp, "/* end of generated code */\n"); + //fprintf(setup_header_fp, "/* end of generated code */\n"); fclose(setup_header_fp); + system("cp u8g2_d_memory.c ../../csrc/."); + system("cp u8g2_d_setup.c ../../csrc/."); + + insert_into_file("../../csrc/u8g2.h", "u8g2_memory.h", "/* u8g2_d_memory.c generated code start */", "/* u8g2_d_memory.c generated code end */"); + insert_into_file("../../csrc/u8g2.h", "u8g2_setup.h", "/* u8g2_d_setup.c generated code start */", "/* u8g2_d_setup.c generated code end */"); + return 0; }