From 416e83ba53d8a495bda74d1fa39a170903dfa721 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Aug 2023 16:21:34 +0800 Subject: [PATCH] update 2023-08-24 16:21:34 --- .../luasrc/model/cbi/mosdns/basic.lua | 2 + luci-app-oled/README.md | 2 +- luci-app-oled/linux/ssd1306.cfg | 26 + luci-app-oled/linux/ssd1306.service | 12 + luci-app-oled/luci-app-oled/.gitignore | 3 + luci-app-oled/{ => luci-app-oled}/LICENSE | 0 luci-app-oled/{ => luci-app-oled}/Makefile | 16 +- .../luasrc/controller/oled.lua | 9 +- .../luasrc/model/cbi/oled/setting.lua | 39 +- .../luasrc/view/oled/status.htm | 0 luci-app-oled/{ => luci-app-oled}/po/zh-cn | 0 luci-app-oled/luci-app-oled/po/zh-tw | 1 + .../{ => luci-app-oled}/po/zh_Hans/oled.po | 19 +- .../{ => luci-app-oled}/po/zh_Hant/oled.po | 0 .../{ => luci-app-oled}/root/etc/config/oled | 8 +- .../luci-app-oled/root/etc/init.d/oled | 115 + .../luci-app-oled/root/etc/uci-defaults/oled | 33 + .../usr/share/rpcd/acl.d/luci-app-oled.json | 0 .../src/Example_Code/.clang-format | 183 ++ .../src/Example_Code/example_app.c | 602 ++++ .../src/Example_Code/example_app.h | 17 +- .../luci-app-oled/src/Example_Code/main.c | 840 +++++ .../src/I2C_Library/.clang-format | 183 ++ .../{ => luci-app-oled}/src/I2C_Library/I2C.c | 114 +- .../{ => luci-app-oled}/src/I2C_Library/I2C.h | 35 +- luci-app-oled/{ => luci-app-oled}/src/LICENSE | 0 luci-app-oled/luci-app-oled/src/Makefile | 30 + .../{ => luci-app-oled}/src/README.md | 0 .../src/SSD1306_OLED_Library/.clang-format | 183 ++ .../src/SSD1306_OLED_Library/SSD1306_OLED.c | 2376 +++++++++++++++ .../src/SSD1306_OLED_Library/SSD1306_OLED.h | 216 ++ .../src/SSD1306_OLED_Library/gfxfont.h | 18 + luci-app-oled/root/etc/init.d/oled | 140 - luci-app-oled/root/etc/uci-defaults/oled | 11 - luci-app-oled/root/usr/sbin/netspeed | 20 - luci-app-oled/src/Example_Code/Main.c | 232 -- luci-app-oled/src/Example_Code/example_app.c | 650 ---- luci-app-oled/src/Makefile | 19 - .../src/SSD1306_OLED_Library/SSD1306_OLED.c | 2713 ----------------- .../src/SSD1306_OLED_Library/SSD1306_OLED.h | 202 -- .../src/SSD1306_OLED_Library/gfxfont.h | 18 - v2ray-geodata/Makefile | 4 +- 42 files changed, 4949 insertions(+), 4142 deletions(-) create mode 100644 luci-app-oled/linux/ssd1306.cfg create mode 100644 luci-app-oled/linux/ssd1306.service create mode 100644 luci-app-oled/luci-app-oled/.gitignore rename luci-app-oled/{ => luci-app-oled}/LICENSE (100%) rename luci-app-oled/{ => luci-app-oled}/Makefile (62%) rename luci-app-oled/{ => luci-app-oled}/luasrc/controller/oled.lua (72%) rename luci-app-oled/{ => luci-app-oled}/luasrc/model/cbi/oled/setting.lua (82%) rename luci-app-oled/{ => luci-app-oled}/luasrc/view/oled/status.htm (100%) rename luci-app-oled/{ => luci-app-oled}/po/zh-cn (100%) create mode 120000 luci-app-oled/luci-app-oled/po/zh-tw rename luci-app-oled/{ => luci-app-oled}/po/zh_Hans/oled.po (89%) rename luci-app-oled/{ => luci-app-oled}/po/zh_Hant/oled.po (100%) rename luci-app-oled/{ => luci-app-oled}/root/etc/config/oled (82%) create mode 100755 luci-app-oled/luci-app-oled/root/etc/init.d/oled create mode 100644 luci-app-oled/luci-app-oled/root/etc/uci-defaults/oled rename luci-app-oled/{ => luci-app-oled}/root/usr/share/rpcd/acl.d/luci-app-oled.json (100%) create mode 100644 luci-app-oled/luci-app-oled/src/Example_Code/.clang-format create mode 100644 luci-app-oled/luci-app-oled/src/Example_Code/example_app.c rename luci-app-oled/{ => luci-app-oled}/src/Example_Code/example_app.h (63%) create mode 100644 luci-app-oled/luci-app-oled/src/Example_Code/main.c create mode 100644 luci-app-oled/luci-app-oled/src/I2C_Library/.clang-format rename luci-app-oled/{ => luci-app-oled}/src/I2C_Library/I2C.c (83%) rename luci-app-oled/{ => luci-app-oled}/src/I2C_Library/I2C.h (76%) rename luci-app-oled/{ => luci-app-oled}/src/LICENSE (100%) create mode 100644 luci-app-oled/luci-app-oled/src/Makefile rename luci-app-oled/{ => luci-app-oled}/src/README.md (100%) create mode 100644 luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/.clang-format create mode 100644 luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c create mode 100644 luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h create mode 100644 luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h delete mode 100755 luci-app-oled/root/etc/init.d/oled delete mode 100644 luci-app-oled/root/etc/uci-defaults/oled delete mode 100755 luci-app-oled/root/usr/sbin/netspeed delete mode 100644 luci-app-oled/src/Example_Code/Main.c delete mode 100644 luci-app-oled/src/Example_Code/example_app.c delete mode 100644 luci-app-oled/src/Makefile delete mode 100644 luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c delete mode 100644 luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h delete mode 100644 luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h diff --git a/luci-app-mosdns/luasrc/model/cbi/mosdns/basic.lua b/luci-app-mosdns/luasrc/model/cbi/mosdns/basic.lua index 5311d9d45..7c9b29a05 100644 --- a/luci-app-mosdns/luasrc/model/cbi/mosdns/basic.lua +++ b/luci-app-mosdns/luasrc/model/cbi/mosdns/basic.lua @@ -83,6 +83,8 @@ o:value("223.6.6.6", "223.6.6.6 (AliDNS Secondary)") o:value("114.114.114.114", "114.114.114.114 (114DNS Primary)") o:value("114.114.115.115", "114.114.115.115 (114DNS Secondary)") o:value("180.76.76.76", "180.76.76.76 (Baidu DNS)") +o:value("8.8.8.8", "8.8.8.8 (Google DNS)") +o:value("1.1.1.1", "1.1.1.1 (CloudFlare DNS)") o.default = "119.29.29.29" o:depends("configfile", "/etc/mosdns/config.yaml") diff --git a/luci-app-oled/README.md b/luci-app-oled/README.md index 8f78c1d2b..4b227cfae 100644 --- a/luci-app-oled/README.md +++ b/luci-app-oled/README.md @@ -1,6 +1,6 @@ # luci-app-oled -This is the LuCI app written for openwrt (**tested ~~only~~ on NanoPi R2S**) which supports ssd 1306 0.91' oled display. +This is the LuCI app written for openwrt (**tested on Hinlink H69K**) which supports ssd 1306 0.91' oled display. **Raspberry Pi CM4** diff --git a/luci-app-oled/linux/ssd1306.cfg b/luci-app-oled/linux/ssd1306.cfg new file mode 100644 index 000000000..5391b8c09 --- /dev/null +++ b/luci-app-oled/linux/ssd1306.cfg @@ -0,0 +1,26 @@ +i2cDevPath = "/dev/i2c-5"; +from = 0; +to = 1440; +neetInit = 1; +rotate = 1; +interval = 60; +displayInvertNormal = 0; +displayDate = 1; +displayIp = 0; +ipIfName = "eth0"; +displayNetSpeed = 0; +speedIfName = "eth0"; +displayCpuTemp = 0; +displayCpuFreq = 0; +drawLine = 1; +drawRect = 0; +fillRect = 0; +drawCircle = 0; +drawRoundCircle = 0; +fillRoundCircle = 0; +drawTriangle = 0; +fillTriangle = 0; +displayBitmap = 0; +drawBitmapEg = 0; +scroll = 1; +scrollText = "H69K-Max"; diff --git a/luci-app-oled/linux/ssd1306.service b/luci-app-oled/linux/ssd1306.service new file mode 100644 index 000000000..f21499974 --- /dev/null +++ b/luci-app-oled/linux/ssd1306.service @@ -0,0 +1,12 @@ +[Unit] +Description=OLED ssd1306 display service +After=network.target + +[Service] +Type=forking +ExecStart=/usr/bin/ssd1306 --config=/etc/ssd1306.cfg +ExecReload=/bin/kill -s HUP $MAINPID +KillMode=mixed + +[Install] +WantedBy=multi-user.target diff --git a/luci-app-oled/luci-app-oled/.gitignore b/luci-app-oled/luci-app-oled/.gitignore new file mode 100644 index 000000000..7df52d1f0 --- /dev/null +++ b/luci-app-oled/luci-app-oled/.gitignore @@ -0,0 +1,3 @@ +*.o +src/oled +src/ssd1306 diff --git a/luci-app-oled/LICENSE b/luci-app-oled/luci-app-oled/LICENSE similarity index 100% rename from luci-app-oled/LICENSE rename to luci-app-oled/luci-app-oled/LICENSE diff --git a/luci-app-oled/Makefile b/luci-app-oled/luci-app-oled/Makefile similarity index 62% rename from luci-app-oled/Makefile rename to luci-app-oled/luci-app-oled/Makefile index 316a36a0e..be7f78d0f 100644 --- a/luci-app-oled/Makefile +++ b/luci-app-oled/luci-app-oled/Makefile @@ -6,16 +6,20 @@ # include $(TOPDIR)/rules.mk -PKG_NAME:=luci-app-oled + LUCI_Title:=LuCI support for ssd1306 0.91\' 138x32 display -LUCI_PKGARCH:=all -LUCI_DEPENDS:=+i2c-tools +coreutils-nohup +libuci -PKG_VERSION:=1.0 -PKG_RELEASE:=1.0 +LUCI_DEPENDS:=+libconfig +LUCI_PKGARCH:=$(if $(realpath src/Makefile),,all) +PKG_VERSION:=20230823 +PKG_RELEASE:=1 PKG_LICENSE:=GPLv3 PKG_LINCESE_FILES:=LICENSE -PKF_MAINTAINER:=natelol +PKG_MAINTAINER:=natelol + +define Package/luci-app-oled/conffiles +/etc/config/oled +endef include $(TOPDIR)/feeds/luci/luci.mk diff --git a/luci-app-oled/luasrc/controller/oled.lua b/luci-app-oled/luci-app-oled/luasrc/controller/oled.lua similarity index 72% rename from luci-app-oled/luasrc/controller/oled.lua rename to luci-app-oled/luci-app-oled/luasrc/controller/oled.lua index 835b054c1..630ea4387 100644 --- a/luci-app-oled/luasrc/controller/oled.lua +++ b/luci-app-oled/luci-app-oled/luasrc/controller/oled.lua @@ -4,7 +4,12 @@ function index() if not nixio.fs.access("/etc/config/oled") then return end - entry({"admin", "services", "oled"}, alias("admin", "services", "oled", "setting"),_("OLED"), 10).dependent = true + local uci = require "luci.model.uci".cursor() + local showmenu = uci:get_first("oled", "oled", "showmenu", "0") + if showmenu == "0" then + return + end + entry({"admin", "services", "oled"}, alias("admin", "services", "oled", "setting"),_("OLED"), 90).dependent = true entry({"admin", "services", "oled", "status"}, call("act_status")) entry({"admin", "services", "oled", "setting"}, cbi("oled/setting"),_("Setting"),30).leaf = true end @@ -14,4 +19,4 @@ function act_status() e.running = luci.sys.call("pgrep -f /usr/bin/oled > /dev/null")==0 luci.http.prepare_content("application/json") luci.http.write_json(e) -end +end diff --git a/luci-app-oled/luasrc/model/cbi/oled/setting.lua b/luci-app-oled/luci-app-oled/luasrc/model/cbi/oled/setting.lua similarity index 82% rename from luci-app-oled/luasrc/model/cbi/oled/setting.lua rename to luci-app-oled/luci-app-oled/luasrc/model/cbi/oled/setting.lua index 7bc8fbf05..36c27daa9 100644 --- a/luci-app-oled/luasrc/model/cbi/oled/setting.lua +++ b/luci-app-oled/luci-app-oled/luasrc/model/cbi/oled/setting.lua @@ -14,6 +14,10 @@ s:tab("screensaver", translate("screensaver")) o = s:taboption("info", Flag, "enable", translate("Enable")) o.default=0 +o = s:taboption("info", Value, "path", translate("I2C PATH")) +o.default='/dev/i2c-0' +o = s:taboption("info", Flag, "rotate", translate("180 degree rotation")) +o.default=0 o = s:taboption("info", Flag, "autoswitch", translate("Enable Auto switch")) o.default=0 from = s:taboption("info", ListValue, "from", translate("From")) @@ -36,26 +40,27 @@ o = s:taboption("info", Flag, "date", translate("Date"), translate('Format YYYY- o.default=0 o = s:taboption("info", Flag, "lanip", translate("IP"), translate("LAN IP address")) o.default=0 +o = s:taboption("info", Value, "ipifname", translate("which eth to monitor")) +o:depends("lanip",'1') +o.default='br-lan' o = s:taboption("info", Flag, "cputemp", translate("CPU temperature")) o.default=0 o = s:taboption("info", Flag, "cpufreq", translate("CPU frequency")) o.default=0 o = s:taboption("info", Flag, "netspeed", translate("Network speed"), translate("1Mbps(m/s)=1,000Kbps(k/s)=1,000,000bps(b/s)")) o.default=0 -o = s:taboption("info", ListValue, "netsource", translate("which eth to monitor")) -o:value("eth0","eth0") -o:value("eth1","eth1") +o = s:taboption("info", Value, "netsource", translate("which eth to monitor")) o:depends("netspeed",'1') o.default='eth0' o = s:taboption("info", Value, "time", translate("Display interval(s)"), translate('Screensaver will activate in set seconds')) o.default=0 --screensaver options-- -o = s:taboption("screensaver", Flag, "scroll", translate("Scroll Text")) -o.default=1 -o = s:taboption("screensaver", Value, "text", translate("Text you want to scroll")) -o:depends("scroll",'1') -o.default='OPENWRT' +o = s:taboption("screensaver", Flag, "scroll", translate("Scroll Text")) +o.default=1 +o = s:taboption("screensaver", Value, "text", translate("Text you want to scroll")) +o:depends("scroll",'1') +o.default='OPENWRT' o = s:taboption("screensaver", Flag, "drawline", translate("Draw Many Lines")) o.default=0 o = s:taboption("screensaver", Flag, "drawrect", translate("Draw Rectangles")) @@ -80,21 +85,3 @@ o = s:taboption("screensaver", Flag, "drawbitmapeg", translate("Draw a bitmap an o.default=0 return m - - - - - - - - - - - - - - - - - ---- diff --git a/luci-app-oled/luasrc/view/oled/status.htm b/luci-app-oled/luci-app-oled/luasrc/view/oled/status.htm similarity index 100% rename from luci-app-oled/luasrc/view/oled/status.htm rename to luci-app-oled/luci-app-oled/luasrc/view/oled/status.htm diff --git a/luci-app-oled/po/zh-cn b/luci-app-oled/luci-app-oled/po/zh-cn similarity index 100% rename from luci-app-oled/po/zh-cn rename to luci-app-oled/luci-app-oled/po/zh-cn diff --git a/luci-app-oled/luci-app-oled/po/zh-tw b/luci-app-oled/luci-app-oled/po/zh-tw new file mode 120000 index 000000000..b241e95bd --- /dev/null +++ b/luci-app-oled/luci-app-oled/po/zh-tw @@ -0,0 +1 @@ +zh_Hant \ No newline at end of file diff --git a/luci-app-oled/po/zh_Hans/oled.po b/luci-app-oled/luci-app-oled/po/zh_Hans/oled.po similarity index 89% rename from luci-app-oled/po/zh_Hans/oled.po rename to luci-app-oled/luci-app-oled/po/zh_Hans/oled.po index bc3f8b056..ae01eab33 100644 --- a/luci-app-oled/po/zh_Hans/oled.po +++ b/luci-app-oled/luci-app-oled/po/zh_Hans/oled.po @@ -5,15 +5,17 @@ msgstr "Content-Type: text/plain; charset=UTF-8" msgid "" "A LuCI app that helps you config your oled display (SSD1306, 0.91', 128X32) " "with screensavers!

Any issues, please go to:" -msgstr "这是一款支持在ssd1306,0.91寸,128x32像素的oled显示屏上显示你要的信息,包含屏保的程序。

任何问题请到:" +msgstr "" +"这是一款支持在ssd1306,0.91寸,128x32像素的oled显示屏上显示你要的信息,包含屏" +"保的程序。

任何问题请到:" #: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:24 msgid "CPU frequency" -msgstr "CPU频率" +msgstr "CPU 频率" #: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:22 msgid "CPU temperature" -msgstr "CPU温度" +msgstr "CPU 温度" msgid "Scroll Text" msgstr "文字滚动" @@ -52,6 +54,7 @@ msgstr "信息显示间隔(秒)" #: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28 msgid "Screensaver will activate in set seconds" msgstr "屏保每间隔设置的时间运行一次" + #: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:32 msgid "Draw Many Lines" msgstr "直线" @@ -100,6 +103,10 @@ msgstr "方形填充" msgid "Format YYYY-MM-DD HH:MM:SS" msgstr "日期格式 YYYY-MM-DD HH:MM:SS" +#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:17 +msgid "I2C PATH" +msgstr "I2C 路径" + #: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20 msgid "IP" msgstr "" @@ -114,7 +121,7 @@ msgstr "反转" #: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20 msgid "LAN IP address" -msgstr "LAN地址" +msgstr "LAN 地址" #: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:10 msgid "NOT RUNNING" @@ -141,3 +148,7 @@ msgstr "设置" #: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:13 msgid "screensaver" msgstr "屏保" + +#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:19 +msgid "180 degree rotation" +msgstr "180 度旋转" diff --git a/luci-app-oled/po/zh_Hant/oled.po b/luci-app-oled/luci-app-oled/po/zh_Hant/oled.po similarity index 100% rename from luci-app-oled/po/zh_Hant/oled.po rename to luci-app-oled/luci-app-oled/po/zh_Hant/oled.po diff --git a/luci-app-oled/root/etc/config/oled b/luci-app-oled/luci-app-oled/root/etc/config/oled similarity index 82% rename from luci-app-oled/root/etc/config/oled rename to luci-app-oled/luci-app-oled/root/etc/config/oled index 2251da946..3c65ee716 100644 --- a/luci-app-oled/root/etc/config/oled +++ b/luci-app-oled/luci-app-oled/root/etc/config/oled @@ -1,4 +1,6 @@ config oled + option showmenu '0' + option enable '0' option drawline '0' option drawrect '0' option fillrect '0' @@ -13,13 +15,15 @@ config oled option date '1' option netspeed '0' option lanip '1' + option ipifname 'br-lan' option cpufreq '1' option cputemp '1' option time '60' - option enable '0' option from '0' option to '1440' option autoswitch '0' - option scroll '1' + option rotate '0' + option scroll '0' option text 'OPENWRT' option netsource 'eth0' + option path '/dev/i2c-0' diff --git a/luci-app-oled/luci-app-oled/root/etc/init.d/oled b/luci-app-oled/luci-app-oled/root/etc/init.d/oled new file mode 100755 index 000000000..e3216e671 --- /dev/null +++ b/luci-app-oled/luci-app-oled/root/etc/init.d/oled @@ -0,0 +1,115 @@ +#!/bin/sh /etc/rc.common + +START=88 +STOP=11 +USE_PROCD=1 +PROG=/usr/bin/oled + +get_section() { + eval "export -n ${2}=\"$1\"" + return 1 +} + +start_service() { + local mainsection + config_load oled + config_foreach get_section oled mainsection + local section=$mainsection + + local enabled ; config_get enabled "$section" enable 0 + if [[ $enabled -eq 0 ]]; then + return 1 + fi + + procd_open_instance + procd_set_param command ${PROG} + procd_append_param command --needInit + + local param + # default /dev/i2c-0 + config_get param "$section" path + [ "$param" != "" ] && procd_append_param command --i2cDevPath="$param" + + # from begin_minitues to end_minitues + # default 0 - 1440 + config_get param "$section" from + [ "$param" != "" ] && procd_append_param command --from="$param" + config_get param "$section" to + [ "$param" != "" ] && procd_append_param command --to="$param" + + config_get param "$section" date + [ "$param" == "1" ] && procd_append_param command --displayDate + + config_get param "$section" lanip + [ "$param" == "1" ] && procd_append_param command --displayIp + config_get param "$section" ipifname + if [ "$param" != "" ];then + procd_append_param command --ipIfName="$param" + else + procd_append_param command --ipIfName="br-lan" + fi + + config_get param "$section" cputemp + [ "$param" == "1" ] && procd_append_param command --displayCpuTemp + + config_get param "$section" cpufreq + [ "$param" == "1" ] && procd_append_param command --displayCpuFreq + + config_get param "$section" netspeed + [ "$param" == "1" ] && procd_append_param command --displayNetSpeed + # default eth0 + config_get param "$section" netsource + [ "$param" != "" ] && procd_append_param command --speedIfName="$param" + + # default 60 + config_get param "$section" time + [ "$param" != "" ] && procd_append_param command --interval="$param" + + config_get param "$section" drawline + [ "$param" == "1" ] && procd_append_param command --drawLine + + config_get param "$section" drawrect + [ "$param" == "1" ] && procd_append_param command --drawRect + + config_get param "$section" fillrect + [ "$param" == "1" ] && procd_append_param command --fillRect + + config_get param "$section" drawcircle + [ "$param" == "1" ] && procd_append_param command --drawCircle + + config_get param "$section" drawroundrect + [ "$param" == "1" ] && procd_append_param command --drawRoundCircle + + config_get param "$section" fillroundrect + [ "$param" == "1" ] && procd_append_param command --fillRoundCircle + + config_get param "$section" drawtriangle + [ "$param" == "1" ] && procd_append_param command --drawTriangle + + config_get param "$section" filltriangle + [ "$param" == "1" ] && procd_append_param command --fillTriangle + + config_get param "$section" displaybitmap + [ "$param" == "1" ] && procd_append_param command --displayBitmap + + config_get param "$section" drawbitmapeg + [ "$param" == "1" ] && procd_append_param command --drawBitmapEg + + config_get param "$section" displayinvertnormal + [ "$param" == "1" ] && procd_append_param command --displayInvertNormal + + config_get param "$section" rotate + [ "$param" == "1" ] && procd_append_param command --rotate + + config_get param "$section" scroll + [ "$param" == "1" ] && procd_append_param command --scroll + config_get param "$section" text + [ "$param" != "" ] && procd_append_param command --scrollText="$param" + + procd_set_param respawn + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger "oled" +} diff --git a/luci-app-oled/luci-app-oled/root/etc/uci-defaults/oled b/luci-app-oled/luci-app-oled/root/etc/uci-defaults/oled new file mode 100644 index 000000000..828832d16 --- /dev/null +++ b/luci-app-oled/luci-app-oled/root/etc/uci-defaults/oled @@ -0,0 +1,33 @@ +#!/bin/sh + +uci_write_config() { + [[ `uci -q get oled.@oled[0].showmenu` -eq 1 ]] && return + uci -q batch <<-EOF >/dev/null + set oled.@oled[0].showmenu="1" + set oled.@oled[0].enable="1" + set oled.@oled[0].path="$1" + set oled.@oled[0].rotate="$2" + set oled.@oled[0].netspeed="$3" + set oled.@oled[0].netsource="$4" + commit oled +EOF +} + +. /lib/functions/system.sh + +case "$(board_name)" in +hinlink,opc-h69k) + uci_write_config '/dev/i2c-5' 1 1 eth0 + ;; +esac + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@oled[-1] + add ucitrack oled + set ucitrack.@oled[-1].init=oled + commit ucitrack +EOF + +sed -e "/\/etc\/init\.d\/oled/d" -i /etc/crontabs/root && /etc/init.d/cron reload +rm -rf /tmp/luci-* +exit 0 diff --git a/luci-app-oled/root/usr/share/rpcd/acl.d/luci-app-oled.json b/luci-app-oled/luci-app-oled/root/usr/share/rpcd/acl.d/luci-app-oled.json similarity index 100% rename from luci-app-oled/root/usr/share/rpcd/acl.d/luci-app-oled.json rename to luci-app-oled/luci-app-oled/root/usr/share/rpcd/acl.d/luci-app-oled.json diff --git a/luci-app-oled/luci-app-oled/src/Example_Code/.clang-format b/luci-app-oled/luci-app-oled/src/Example_Code/.clang-format new file mode 100644 index 000000000..5caad4065 --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/Example_Code/.clang-format @@ -0,0 +1,183 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveBitFields: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + - Regex: '.*' + Priority: 3 + SortPriority: 0 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Auto +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +IndentWidth: 8 +TabWidth: 8 +UseCRLF: false +UseTab: Always +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE +... + diff --git a/luci-app-oled/luci-app-oled/src/Example_Code/example_app.c b/luci-app-oled/luci-app-oled/src/Example_Code/example_app.c new file mode 100644 index 000000000..313d09553 --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/Example_Code/example_app.c @@ -0,0 +1,602 @@ +/* + * MIT License + +Copyright (c) 2017 DeeplyEmbedded + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * example_app.c + * + * Created on : Sep 6, 2017 + * Author : Vinay Divakar + * Website : www.deeplyembedded.org + */ + +/* Lib Includes */ +#include "example_app.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SSD1306_OLED.h" + +#define BUFMAX SSD1306_LCDWIDTH *SSD1306_LCDHEIGHT + +/* MACRO's */ +#define LOGO16_GLCD_HEIGHT 16 +#define LOGO16_GLCD_WIDTH 16 +#define NUMFLAKES 10 +#define XPOS 0 +#define YPOS 1 +#define DELTAY 2 + +#define TIMESIZE 64 +// temperature +#define TEMPPATH "/sys/class/thermal/thermal_zone0/temp" +#define TEMPSIZE 5 +// cpu +#define FREQSIZE 8 +#define FREQPATH "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq" +// ip +#define IPSIZE 20 + +/* Extern volatile */ +extern volatile unsigned char flag; + +/* Bit Map - Taken from Adafruit SSD1306 OLED Library */ +static const unsigned char logo16_glcd_bmp[] = { + 0b00000000, 0b11000000, 0b00000001, 0b11000000, 0b00000001, 0b11000000, + 0b00000011, 0b11100000, 0b11110011, 0b11100000, 0b11111110, 0b11111000, + 0b01111110, 0b11111111, 0b00110011, 0b10011111, 0b00011111, 0b11111100, + 0b00001101, 0b01110000, 0b00011011, 0b10100000, 0b00111111, 0b11100000, + 0b00111111, 0b11110000, 0b01111100, 0b11110000, 0b01110000, 0b01110000, + 0b00000000, 0b00110000}; + +FILE *fp; +char content_buff[BUFMAX]; +char buf[BUFMAX]; +int display_offset = 7; +/* draw many lines */ +void testdrawline() { + short i = 0; + for (i = 0; i < SSD1306_LCDWIDTH; i += 4) { + drawLine(0, 0, i, SSD1306_LCDHEIGHT - 1, WHITE); + Display(); + usleep(1000); + } + for (i = 0; i < SSD1306_LCDHEIGHT; i += 4) { + drawLine(0, 0, SSD1306_LCDWIDTH - 1, i, WHITE); + Display(); + usleep(1000); + } + usleep(250000); + + clearDisplay(); + for (i = 0; i < SSD1306_LCDWIDTH; i += 4) { + drawLine(0, SSD1306_LCDHEIGHT - 1, i, 0, WHITE); + Display(); + usleep(1000); + } + for (i = SSD1306_LCDHEIGHT - 1; i >= 0; i -= 4) { + drawLine(0, SSD1306_LCDHEIGHT - 1, SSD1306_LCDWIDTH - 1, i, + WHITE); + Display(); + usleep(1000); + } + usleep(250000); + + clearDisplay(); + for (i = SSD1306_LCDWIDTH - 1; i >= 0; i -= 4) { + drawLine(SSD1306_LCDWIDTH - 1, SSD1306_LCDHEIGHT - 1, i, 0, + WHITE); + Display(); + usleep(1000); + } + for (i = SSD1306_LCDHEIGHT - 1; i >= 0; i -= 4) { + drawLine(SSD1306_LCDWIDTH - 1, SSD1306_LCDHEIGHT - 1, 0, i, + WHITE); + Display(); + usleep(1000); + } + usleep(250000); + + clearDisplay(); + for (i = 0; i < SSD1306_LCDHEIGHT; i += 4) { + drawLine(SSD1306_LCDWIDTH - 1, 0, 0, i, WHITE); + Display(); + usleep(1000); + } + for (i = 0; i < SSD1306_LCDWIDTH; i += 4) { + drawLine(SSD1306_LCDWIDTH - 1, 0, i, SSD1306_LCDHEIGHT - 1, + WHITE); + Display(); + usleep(1000); + } + usleep(250000); +} + +/* draw rectangles */ +void testdrawrect() { + short i = 0; + for (i = 0; i < SSD1306_LCDHEIGHT / 2; i += 2) { + drawRect(i, i, SSD1306_LCDWIDTH - 2 * i, + SSD1306_LCDHEIGHT - 2 * i, WHITE); + Display(); + usleep(1000); + } +} + +/* draw multiple rectangles */ +void testfillrect() { + unsigned char color = 1; + short i = 0; + for (i = 0; i < SSD1306_LCDHEIGHT / 2; i += 3) { + // alternate colors + fillRect(i, i, SSD1306_LCDWIDTH - i * 2, + SSD1306_LCDHEIGHT - i * 2, color % 2); + Display(); + usleep(1000); + color++; + } +} + +/* draw mulitple circles */ +void testdrawcircle() { + short i = 0; + for (i = 0; i < SSD1306_LCDHEIGHT; i += 2) { + drawCircle(SSD1306_LCDWIDTH / 2, SSD1306_LCDHEIGHT / 2, i, + WHITE); + Display(); + usleep(1000); + } +} + +/*draw a white circle, 10 pixel radius */ +void testdrawroundrect() { + short i = 0; + for (i = 0; i < SSD1306_LCDHEIGHT / 2 - 2; i += 2) { + drawRoundRect(i, i, SSD1306_LCDWIDTH - 2 * i, + SSD1306_LCDHEIGHT - 2 * i, SSD1306_LCDHEIGHT / 4, + WHITE); + Display(); + usleep(1000); + } +} + +/* Fill the round rectangle */ +void testfillroundrect() { + short color = WHITE, i = 0; + for (i = 0; i < SSD1306_LCDHEIGHT / 2 - 2; i += 2) { + fillRoundRect(i, i, SSD1306_LCDWIDTH - 2 * i, + SSD1306_LCDHEIGHT - 2 * i, SSD1306_LCDHEIGHT / 4, + color); + if (color == WHITE) + color = BLACK; + else + color = WHITE; + Display(); + usleep(1000); + } +} + +/* Draw triangles */ +void testdrawtriangle() { + short i = 0; + for (i = 0; i < MIN(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) / 2; i += 5) { + drawTriangle( + SSD1306_LCDWIDTH / 2, SSD1306_LCDHEIGHT / 2 - i, + SSD1306_LCDWIDTH / 2 - i, SSD1306_LCDHEIGHT / 2 + i, + SSD1306_LCDWIDTH / 2 + i, SSD1306_LCDHEIGHT / 2 + i, WHITE); + Display(); + usleep(1000); + } +} + +/* Fill triangles */ +void testfilltriangle() { + unsigned char color = WHITE; + short i = 0; + for (i = MIN(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT) / 2; i > 0; i -= 5) { + fillTriangle( + SSD1306_LCDWIDTH / 2, SSD1306_LCDHEIGHT / 2 - i, + SSD1306_LCDWIDTH / 2 - i, SSD1306_LCDHEIGHT / 2 + i, + SSD1306_LCDWIDTH / 2 + i, SSD1306_LCDHEIGHT / 2 + i, WHITE); + if (color == WHITE) + color = BLACK; + else + color = WHITE; + Display(); + usleep(1000); + } +} + +/* Display a bunch of characters and emoticons */ +void testdrawchar() { + unsigned char i = 0; + setTextSize(1); + setTextColor(WHITE); + setCursor(0, 0); + + for (i = 0; i < 168; i++) { + if (i == '\n') continue; + oled_write(i); + if ((i > 0) && (i % 21 == 0)) println(); + } + Display(); + usleep(1000); +} + +/* Display "scroll" and scroll around */ +void testscrolltext(char *str) { + setTextSize(2); + setTextColor(WHITE); + setCursor(10, 8); + sprintf(buf, "%s", str); + print_strln(buf); + Display(); + usleep(1000); + startscrollright(0x00, 0x0F); + usleep(5000000); + stopscroll(); + usleep(1000000); + startscrollleft(0x00, 0x0F); + usleep(5000000); + stopscroll(); + usleep(1000000); + startscrolldiagright(0x00, 0x07); + usleep(5000000); + startscrolldiagleft(0x00, 0x07); + usleep(5000000); + stopscroll(); +} + +/* Display Texts */ +void display_texts() { + setTextSize(1); + setTextColor(WHITE); + setCursor(10, 0); + print_str("HELLO FELLAS!"); + println(); + printFloat_ln(3.141592, 4); // Print 4 No's after the decimal Pt. + printNumber_L_ln(-1234, DEC); + printNumber_UC_ln(170, BIN); + setTextSize(2); + setTextColor(WHITE); + print_str("0x"); + printNumber_UL_ln(0xDEADBEEF, HEX); +} + +/* Display miniature bitmap */ +void display_bitmap() { drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1); } + +/* Invert Display and Normalize it */ +void display_invert_normal() { + invertDisplay(SSD1306_INVERT_DISPLAY); + usleep(1000000); + invertDisplay(SSD1306_NORMALIZE_DISPLAY); + usleep(1000000); +} + +/* Draw a bitmap and 'animate' movement */ +void testdrawbitmap(const unsigned char *bitmap, unsigned char w, + unsigned char h) { + unsigned char icons[NUMFLAKES][3], f = 0; + + // initialize + for (f = 0; f < NUMFLAKES; f++) { + icons[f][XPOS] = rand() % SSD1306_LCDWIDTH; + icons[f][YPOS] = 0; + icons[f][DELTAY] = (rand() % 5) + 1; + + /* Looks kinna ugly to me - Un-Comment if you need it */ + // print_str("x: "); + // printNumber_UC(icons[f][XPOS], DEC); + // print_str("y: "); + // printNumber_UC(icons[f][YPOS], DEC); + // print_str("dy: "); + // printNumber_UC(icons[f][DELTAY], DEC); + } + + while (flag != 5) { + // draw each icon + for (f = 0; f < NUMFLAKES; f++) { + drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, + WHITE); + } + Display(); + usleep(200000); + + // then erase it + move it + for (f = 0; f < NUMFLAKES; f++) { + drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, + BLACK); + + // move it + icons[f][YPOS] += icons[f][DELTAY]; + + // if its gone, reinit + if (icons[f][YPOS] > SSD1306_LCDHEIGHT) { + icons[f][XPOS] = rand() % SSD1306_LCDWIDTH; + icons[f][YPOS] = 0; + icons[f][DELTAY] = (rand() % 5) + 1; + } + } + } +} + +/* Draw bitmap and animate */ +void testdrawbitmap_eg() { + setTextSize(1); + setTextColor(WHITE); + setCursor(10, 0); + testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH); +} + +/* Intro */ +void deeplyembedded_credits() { + setTextSize(1); + setTextColor(WHITE); + setCursor(1, 0); + print_strln("deeplyembedded.org"); + println(); + print_strln("Author:Vinay Divakar"); + println(); + println(); + print_strln("THANK YOU"); +} + +void testdate(int mode, int y) { + time_t rawtime; + time_t curtime; + uint8_t timebuff[TIMESIZE]; + curtime = time(NULL); + time(&rawtime); + switch (mode) { + case CENTER: + setTextSize(2); + strftime(timebuff, 80, "%H:%M", localtime(&rawtime)); + sprintf(buf, "%s", timebuff); + setCursor((127 - strlen(buf) * 11) / 2 - 4, y); + break; + case FULL: + setTextSize(1); + strftime(timebuff, 80, "%Y-%m-%d %H:%M:%S", + localtime(&rawtime)); + sprintf(buf, "%s", timebuff); + setCursor(display_offset, y); + } + print_strln(buf); +} + +char *get_ip_addr(char *ifname) { + int n; + struct ifreq ifr; + + n = socket(AF_INET, SOCK_DGRAM, 0); + // Type of address to retrieve - IPv4 IP address + ifr.ifr_addr.sa_family = AF_INET; + // Copy the interface name in the ifreq structure + strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); + ioctl(n, SIOCGIFADDR, &ifr); + close(n); + return inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); +} + +void testip(int mode, int y, char *ifname) { + setTextSize(1); + switch (mode) { + case CENTER: + setTextSize(1); + sprintf(buf, "%s", get_ip_addr(ifname)); + setCursor((127 - strlen(buf) * 6) / 2, y + 4); + break; + + case FULL: + setTextSize(1); + sprintf(buf, "IP:%s", get_ip_addr(ifname)); + setCursor(display_offset, y); + } + print_strln(buf); +} + +void testcputemp(int mode, int y) { + if ((fp = fopen(TEMPPATH, "r")) != NULL) { + if (fgets(content_buff, TEMPSIZE, fp)) + ; + fclose(fp); + switch (mode) { + case CENTER: + setTextSize(2); + sprintf(buf, "%.2f", + atoi(content_buff) / 100.0); + setCursor( + (127 - (strlen(buf) + 2) * 11) / 2 - 4, y); + print_str(buf); + oled_write(0); + oled_write(67); + drawCircle(getCursorX() - 16, getCursorY() + 3, + 2, WHITE); + break; + case FULL: + setTextSize(1); + sprintf(buf, "CPU TEMP:%.2f", + atoi(content_buff) / 100.0); + setCursor(display_offset, y); + print_str(buf); + oled_write(0); + oled_write(67); + drawCircle(getCursorX() - 8, getCursorY() + 1, + 1, WHITE); + } + } +} + +void testcpufreq(int mode, int y) { + if ((fp = fopen(FREQPATH, "r")) != NULL) { + if (fgets(content_buff, FREQSIZE, fp)) + ; + fclose(fp); + switch (mode) { + case CENTER: + setTextSize(2); + sprintf(buf, "%4dMHz", + atoi(content_buff) / 1000); + setCursor((127 - strlen(buf) * 11) / 2 - 4, y); + break; + case FULL: + setTextSize(1); + sprintf(buf, "CPU FREQ:%4dMHz", + atoi(content_buff) / 1000); + setCursor(display_offset, y); + } + print_strln(buf); + } +} + +void testnetspeed(int mode, int y, unsigned long int rx, unsigned long int tx) { + char tx_str[8], rx_str[8]; + + if (tx < KB_BYTES) { + sprintf(tx_str, "%4dB ", (unsigned int)tx); + } else if (tx >= MB_BYTES) { + sprintf(tx_str, "%4dM ", (unsigned int)tx / MB_BYTES); + } else { + sprintf(tx_str, "%4dK ", (unsigned int)tx / KB_BYTES); + } + + if (rx < KB_BYTES) { + sprintf(rx_str, "%4dB ", (unsigned int)rx); + } else if (rx >= MB_BYTES) { + sprintf(rx_str, "%4dM ", (unsigned int)rx / MB_BYTES); + } else { + sprintf(rx_str, "%4dK ", (unsigned int)rx / KB_BYTES); + } + + // printf("rxspeed: %s txspeed: %s\n", rx_str, tx_str); + switch (mode) { + case SPLIT: + setTextSize(2); + strcpy(buf, tx_str); + setCursor((127 - (strlen(buf) + 1) * 11) / 2, 0); + oled_write(24); + print_str(buf); + + strcpy(buf, rx_str); + setCursor((127 - (strlen(buf) + 1) * 11) / 2, 16); + oled_write(25); + print_str(buf); + break; + case MERGE: + setTextSize(1); + strcpy(buf, tx_str); + setCursor((127 - (2 * strlen(buf) - 1) * 6) / 2 - 4, + y + 4); + oled_write(24); + print_str(buf); + + strcpy(buf, rx_str); + oled_write(25); + print_str(buf); + break; + case FULL: + setTextSize(1); + setCursor(display_offset, y); + oled_write(24); + strcpy(buf, tx_str); + print_str(buf); + + oled_write(25); + strcpy(buf, rx_str); + print_str(buf); + } +} + +void testcpu(int y) { + // freq + setTextSize(1); + setCursor(display_offset, y); + if ((fp = fopen(FREQPATH, "r")) != NULL) { + if (fgets(content_buff, FREQSIZE, fp)) + ; + fclose(fp); + sprintf(buf, "CPU:%4dMHz ", atoi(content_buff) / 1000); + print_str(buf); + } + + // temp + if ((fp = fopen(TEMPPATH, "r")) != NULL) { + if (fgets(content_buff, TEMPSIZE, fp)) + ; + fclose(fp); + sprintf(buf, "%.2f", atoi(content_buff) / 100.0); + print_str(buf); + oled_write(0); + oled_write(67); + drawCircle(getCursorX() - 8, getCursorY() + 1, 1, WHITE); + } +} + +void testprintinfo() { + setTextSize(1); + setTextColor(WHITE); + setCursor(0, 0); + + // date + time_t rawtime; + time_t curtime; + uint8_t timebuff[TIMESIZE]; + curtime = time(NULL); + time(&rawtime); + strftime(timebuff, 80, "%Y-%m-%d_%w %H:%M:%S", localtime(&rawtime)); + sprintf(buf, "%s", timebuff); + print_strln(buf); + + // br-lan ip + sprintf(buf, "IP:%s", get_ip_addr("br-lan")); + print_strln(buf); + + // CPU temp + if ((fp = fopen(FREQPATH, "r")) != NULL) { + if (fgets(content_buff, FREQSIZE, fp)) + ; + fclose(fp); + sprintf(buf, "CPU freq:%d MHz ", atoi(content_buff) / 1000); + print_strln(buf); + } + + // cpu freq + if ((fp = fopen(TEMPPATH, "r")) != NULL) { + if (fgets(content_buff, TEMPSIZE, fp)) + ; + fclose(fp); + sprintf(buf, "CPU temp:%.2f C", atoi(content_buff) / 100.0); + print_strln(buf); + } +} diff --git a/luci-app-oled/src/Example_Code/example_app.h b/luci-app-oled/luci-app-oled/src/Example_Code/example_app.h similarity index 63% rename from luci-app-oled/src/Example_Code/example_app.h rename to luci-app-oled/luci-app-oled/src/Example_Code/example_app.h index eb0435826..6f7ca416e 100644 --- a/luci-app-oled/src/Example_Code/example_app.h +++ b/luci-app-oled/luci-app-oled/src/Example_Code/example_app.h @@ -1,7 +1,10 @@ -#define CENTER 0 //single item display -#define SPLIT 1 //two items +#define CENTER 0 // single item display +#define SPLIT 1 // two items #define MERGE 2 #define FULL 3 +#define KB_BYTES (1024) +#define MB_BYTES (1024 * 1024) +#define GB_BYTES (1024 * 1024 * 1024) void testdrawline(); void testdrawrect(); @@ -16,15 +19,15 @@ void testscrolltext(char *str); void display_texts(); void display_bitmap(); void display_invert_normal(); -void testdrawbitmap(const unsigned char *bitmap, unsigned char w, unsigned char h); +void testdrawbitmap(const unsigned char *bitmap, unsigned char w, + unsigned char h); void testdrawbitmap_eg(); void deeplyembedded_credits(); void testprintinfo(); void testdate(int mode, int y); -void testlanip(int mode, int y); +void testip(int mode, int y, char *ifname); void testcpufreq(int mode, int y); void testcputemp(int mode, int y); -void testnetspeed(int mode, int y); +void testnetspeed(int mode, int y, unsigned long int rx, unsigned long int tx); void testcpu(int y); - - +char *get_ip_addr(char *ifname); diff --git a/luci-app-oled/luci-app-oled/src/Example_Code/main.c b/luci-app-oled/luci-app-oled/src/Example_Code/main.c new file mode 100644 index 000000000..72f8869ef --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/Example_Code/main.c @@ -0,0 +1,840 @@ +/* + * Main.c + * + * Created on : Sep 6, 2017 + * Author : Vinay Divakar + * Description : Example usage of the SSD1306 Driver API's + * Website : www.deeplyembedded.org + */ + +/* Lib Includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Header Files */ +#include "I2C.h" +#include "SSD1306_OLED.h" +#include "example_app.h" + +#define NETSPEED_INTERVAL 1000000 +#define DISPLAY_INTERVAL 1000000 +#define TIME_CHECK_INTERVAL 5000000 + +struct st_config { + unsigned int disp_date; + unsigned int disp_ip; + char *ip_if_name; + unsigned int disp_cpu_temp; + unsigned int disp_cpu_freq; + unsigned int disp_net_speed; + char *speed_if_name; + unsigned int interval; + unsigned int draw_line; + unsigned int draw_rect; + unsigned int fill_rect; + unsigned int draw_circle; + unsigned int draw_round_circle; + unsigned int fill_round_circle; + unsigned int draw_triangle; + unsigned int fill_triangle; + unsigned int disp_bitmap; + unsigned int disp_invert_normal; + unsigned int draw_bitmap_eg; + unsigned int scroll; + char *scroll_text; + char *i2c_dev_path; + unsigned int rotate; + unsigned int need_init; + int from; + int to; +}; + +static void printHelp() { + printf( + "\n\ +Usage: oled [options] ...\n\ +Options:\n\ + --help or -h Display this information.\n\ + --version or -v Display compiler version information.\n\ +\n\ + --config=file or -c file Specify configuration file.\n\ +\n\ + --i2cDevPath=path or -d path Specify the i2c device, default is /dev/i2c-0.\n\ + --from=minutes or -f minites Specify the time(in minutes of day) to start displaying, default is 0.\n\ + --to=minutes or -t minites Specify the time(in minutes of day) to stop displaying, default is 1440.\n\ + --neetInit or -N Turn on init, default is on.\n\ + --interval=n or -l n Specify the display interval, default is 60(s).\n\ + --displayInvertNormal or -I Turn on the invert normal mode.\n\ + --rotate or -H Turn on rotate.\n\ +\n\ + --displayDate or -D Turn on the date display.\n\ + --displayIp or -A Turn on the IP address display.\n\ + --ipIfName=ifname or -a ifname Specify the eth device to display the ip address, default is br-lan.\n\ + --displayNetSpeed or -S Turn on the net speed display.\n\ + --speedIfName=ifname or -s ifname Specify the eth device to display the net speed, default is eth0.\n\ + --displayCpuTemp or -T Turn on the CPU temperature.\n\ + --displayCpuFreq or -F Turn on the CPU frequency.\n\ +\n\ + --drawLine or -L Turn on draw line.\n\ + --drawRect or -W Turn on draw rect.\n\ + --fillRect or -w Turn on fill rect.\n\ + --drawCircle or -C Turn on draw circle.\n\ + --drawRoundCircle or -R Turn on draw round circle.\n\ + --fillRoundCircle or -r Turn on fill round circle.\n\ + --drawTriangle or -G Turn on draw triangle.\n\ + --fillTriangle or -g Turn on fill triangle.\n\ + --displayBitmap or -B Turn on display bitmap.\n\ + --drawBitmapEg or -E Turn on draw bitmap eg.\n\ + --scroll or -O Turn on scroll text.\n\ + --scrollText=text or -o text Specify the scroll text, default is 'Hello world'.\n\ +\n"); +} + +static void printVersion() { + // Code to print version information + printf("Version: 1.0\n"); +} + +static void read_conf_file(const char *filename, struct st_config *stcfg) { + config_t cfg; + config_init(&cfg); + char *buff; + + if (!config_read_file(&cfg, filename)) { + fprintf(stderr, "Error reading configuration file: %s\n", + config_error_text(&cfg)); + config_destroy(&cfg); + exit(EXIT_FAILURE); + } + + config_lookup_int(&cfg, "displayDate", &stcfg->disp_date); + config_lookup_int(&cfg, "displayIp", &stcfg->disp_ip); + + if (config_lookup_string(&cfg, "ipIfName", (const char **)&buff)) { + sprintf(stcfg->ip_if_name, "%s", buff); + } + + config_lookup_int(&cfg, "displayCpuTemp", &stcfg->disp_cpu_temp); + config_lookup_int(&cfg, "displayCpuFreq", &stcfg->disp_cpu_freq); + config_lookup_int(&cfg, "displayNetSpeed", &stcfg->disp_net_speed); + + if (config_lookup_string(&cfg, "speedIfName", (const char **)&buff)) { + sprintf(stcfg->speed_if_name, "%s", buff); + } + + config_lookup_int(&cfg, "interval", &stcfg->interval); + config_lookup_int(&cfg, "drawLine", &stcfg->draw_line); + config_lookup_int(&cfg, "drawRect", &stcfg->draw_rect); + config_lookup_int(&cfg, "fillRect", &stcfg->fill_rect); + config_lookup_int(&cfg, "drawCircle", &stcfg->draw_circle); + config_lookup_int(&cfg, "drawRoundCircle", &stcfg->draw_round_circle); + config_lookup_int(&cfg, "fillRoundCircle", &stcfg->fill_round_circle); + config_lookup_int(&cfg, "drawTriangle", &stcfg->draw_triangle); + config_lookup_int(&cfg, "fillTriangle", &stcfg->fill_triangle); + config_lookup_int(&cfg, "displayBitmap", &stcfg->disp_bitmap); + config_lookup_int(&cfg, "displayInvertNormal", + &stcfg->disp_invert_normal); + config_lookup_int(&cfg, "drawBitmapEg", &stcfg->draw_bitmap_eg); + config_lookup_int(&cfg, "scroll", &stcfg->scroll); + + if (config_lookup_string(&cfg, "scrollText", (const char **)&buff)) { + sprintf(stcfg->scroll_text, "%s", buff); + } + + if (config_lookup_string(&cfg, "i2cDevPath", (const char **)&buff)) { + sprintf(stcfg->i2c_dev_path, "%s", buff); + } + + config_lookup_int(&cfg, "rotate", &stcfg->rotate); + config_lookup_int(&cfg, "needInit", &stcfg->need_init); + config_lookup_int(&cfg, "from", &stcfg->from); + config_lookup_int(&cfg, "to", &stcfg->to); + + config_destroy(&cfg); +} + +static int get_current_minitues() { + time_t rawtime; + struct tm *info; + time(&rawtime); + info = localtime(&rawtime); + // printf("Current local time and date: %s", asctime(info)); + // printf("Current minutues: %d\n", info->tm_hour * 60 + info->tm_min); + return (info->tm_hour * 60 + info->tm_min); +} + +/* Oh Compiler-Please leave me as is */ +volatile unsigned char flag = 0; + +/** Shared variable by the threads */ +static unsigned long int __shared_rx_speed = 0; +static unsigned long int __shared_tx_speed = 0; +static int __shared_sleeped = 0; + +/** Mutual exclusion of the shared variable */ +static pthread_mutex_t __mutex_shared_variable = + (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + +static pthread_mutex_t __mutex_shared_variable1 = + (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER; + +/* thread id */ +static pthread_t tid = 0; +static pthread_t tid1 = 0; + +static float get_uptime() { + FILE *fp1; + float uptime = 0, idletime = 0; + if ((fp1 = fopen("/proc/uptime", "r")) != NULL) { + if (fscanf(fp1, "%f %f", &uptime, &idletime)) + ; + fclose(fp1); + } + return uptime; +} + +static void *pth_time_check(void *arg) { + int now; + struct st_config *stcfg; + stcfg = (struct st_config *)arg; + while (1) { + // Work only during specified time periods + now = get_current_minitues(); + pthread_mutex_lock(&__mutex_shared_variable1); + { + if (stcfg->from != stcfg->to && + (now < stcfg->from || now >= stcfg->to)) { + if (__shared_sleeped == 0) { + clearDisplay(); + Display(); + } + __shared_sleeped = 1; + } else { + __shared_sleeped = 0; + } + } + pthread_mutex_unlock(&__mutex_shared_variable1); + usleep(TIME_CHECK_INTERVAL); + } +} + +static inline int get_sleep_flag() { + int flag; + pthread_mutex_lock(&__mutex_shared_variable1); + { flag = __shared_sleeped; } + pthread_mutex_unlock(&__mutex_shared_variable1); + return flag; +} + +static void *pth_netspeed(char *ifname) { + char rxbytes_path[80]; + char txbytes_path[80]; + unsigned long long int llu_bytes; + unsigned long int rx_bytes = 0, tx_bytes = 0, last_rx_bytes = 0, + last_tx_bytes = 0; + unsigned long int rx_speed, tx_speed; + FILE *fp1; + float last_uptime, uptime; + + sprintf(rxbytes_path, "/sys/class/net/%s/statistics/rx_bytes", ifname); + sprintf(txbytes_path, "/sys/class/net/%s/statistics/tx_bytes", ifname); + last_uptime = get_uptime(); + while (1) { + uptime = get_uptime(); + if ((fp1 = fopen(rxbytes_path, "r")) != NULL) { + if (fscanf(fp1, "%llu", &llu_bytes)) + ; + fclose(fp1); + rx_bytes = llu_bytes % ULONG_MAX; + } else { + last_uptime = uptime; + usleep(NETSPEED_INTERVAL); + continue; + } + + if ((fp1 = fopen(txbytes_path, "r")) != NULL) { + if (fscanf(fp1, "%llu", &llu_bytes)) + ; + fclose(fp1); + tx_bytes = llu_bytes % ULONG_MAX; + } else { + last_uptime = uptime; + usleep(NETSPEED_INTERVAL); + continue; + } + + if ((last_rx_bytes == 0 && last_tx_bytes == 0) || + (rx_bytes < last_rx_bytes) || (tx_bytes < last_tx_bytes) || + (uptime <= last_uptime)) { + last_rx_bytes = rx_bytes; + last_tx_bytes = tx_bytes; + } else { + rx_speed = + (rx_bytes - last_rx_bytes) / (uptime - last_uptime); + tx_speed = + (tx_bytes - last_tx_bytes) / (uptime - last_uptime); + + // write shared variables; + pthread_mutex_lock(&__mutex_shared_variable); + { + __shared_rx_speed = rx_speed; + __shared_tx_speed = tx_speed; + } + pthread_mutex_unlock(&__mutex_shared_variable); + + last_rx_bytes = rx_bytes; + last_tx_bytes = tx_bytes; + } + last_uptime = uptime; + usleep(NETSPEED_INTERVAL); + } +} + +/* Alarm Signal Handler */ +void ALARMhandler(int sig) { + /* Set flag */ + flag = 5; +} + +void BreakDeal(int sig) { + printf("Recived a KILL signal!\n"); + if (tid != 0) { + pthread_cancel(tid); + pthread_join(tid, NULL); + } + if (tid1 != 0) { + pthread_cancel(tid1); + pthread_join(tid1, NULL); + } + clearDisplay(); + usleep(DISPLAY_INTERVAL); + Display(); + exit(0); +} + +int main(int argc, char *argv[]) { + int option; + int option_index = 0; + char *config_file = NULL; + unsigned long int rx_speed, tx_speed; + struct st_config *stcfg; + + static struct option long_options[] = { + {"config", required_argument, 0, 'c'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {"displayDate", no_argument, 0, 'D'}, + {"displayIp", no_argument, 0, 'A'}, + {"ipIfName", required_argument, 0, 'a'}, + {"displayNetSpeed", no_argument, 0, 'S'}, + {"speedIfName", required_argument, 0, 's'}, + {"displayCpuTemp", no_argument, 0, 'T'}, + {"displayCpuFreq", no_argument, 0, 'F'}, + {"displayInvertNormal", no_argument, 0, 'I'}, + {"interval", required_argument, 0, 'l'}, + {"drawLine", no_argument, 0, 'L'}, + {"drawRect", no_argument, 0, 'W'}, + {"fillRect", no_argument, 0, 'w'}, + {"drawCircle", no_argument, 0, 'C'}, + {"drawRoundCircle", no_argument, 0, 'R'}, + {"fillRoundCircle", no_argument, 0, 'r'}, + {"drawTriangle", no_argument, 0, 'G'}, + {"fillTriangle", no_argument, 0, 'g'}, + {"displayBitmap", no_argument, 0, 'B'}, + {"drawBitmapEg", no_argument, 0, 'E'}, + {"scroll", no_argument, 0, 'O'}, + {"scrollText", required_argument, 0, 'o'}, + {"i2cDevPath", required_argument, 0, 'd'}, + {"rotate", no_argument, 0, 'H'}, + {"needInit", no_argument, 0, 'N'}, + {"from", required_argument, 0, 'f'}, + {"to", required_argument, 0, 't'}, + {0, 0, 0, 0}}; + + stcfg = (struct st_config *)malloc(sizeof(struct st_config)); + memset(stcfg, 0, sizeof(struct st_config)); + + /* set default value for config */ + stcfg->need_init = 1; + stcfg->interval = 60; + stcfg->from = 0; + stcfg->to = 1440; + + stcfg->ip_if_name = malloc(sizeof(char) * 20); + sprintf(stcfg->ip_if_name, "br-lan"); + + stcfg->speed_if_name = malloc(sizeof(char) * 20); + sprintf(stcfg->speed_if_name, "eth0"); + + stcfg->scroll_text = malloc(sizeof(char) * 100); + sprintf(stcfg->scroll_text, "Hello"); + + stcfg->i2c_dev_path = malloc(sizeof(char) * 20); + sprintf(stcfg->i2c_dev_path, "%s", I2C_DEV0_PATH); + /* The end of set default value for config */ + + while ((option = getopt_long(argc, argv, + "c:hvDAa:Ss:TFIl:LWwCRrGgBEOo:d:HNf:t:", + long_options, &option_index)) != -1) { + switch (option) { + case 'c': + config_file = optarg; + break; + case 'h': + printHelp(); + exit(EXIT_SUCCESS); + case 'v': + printVersion(); + exit(EXIT_SUCCESS); + case '?': + // Invalid option or missing argument + exit(EXIT_FAILURE); + default: + // Handle other parameters + break; + } + } + + if (config_file != NULL) { + // Read parameters from the configuration file + read_conf_file(config_file, stcfg); + } + + // Update config from the command params + optind = 0; + while ((option = getopt_long(argc, argv, + "c:hvDAa:Ss:TFIl:LWwCRrGgBEOo:d:HNf:t:", + long_options, &option_index)) != -1) { + switch (option) { + case 'D': + stcfg->disp_date = 1; + break; + case 'A': + stcfg->disp_ip = 1; + break; + case 'a': + sprintf(stcfg->ip_if_name, "%s", optarg); + break; + case 'S': + stcfg->disp_net_speed = 1; + break; + case 's': + sprintf(stcfg->speed_if_name, "%s", optarg); + break; + case 'T': + stcfg->disp_cpu_temp = 1; + break; + case 'F': + stcfg->disp_cpu_freq = 1; + break; + case 'I': + stcfg->disp_invert_normal = 1; + break; + case 'l': + stcfg->interval = atoi(optarg); + break; + case 'L': + stcfg->draw_line = 1; + break; + case 'W': + stcfg->draw_rect = 1; + break; + case 'w': + stcfg->fill_rect = 1; + break; + case 'C': + stcfg->draw_circle = 1; + break; + case 'R': + stcfg->draw_round_circle = 1; + break; + case 'r': + stcfg->fill_round_circle = 1; + break; + case 'G': + stcfg->draw_triangle = 1; + break; + case 'g': + stcfg->fill_triangle = 1; + break; + case 'B': + stcfg->disp_bitmap = 1; + break; + case 'E': + stcfg->draw_bitmap_eg = 1; + break; + case 'O': + stcfg->scroll = 1; + break; + case 'o': + sprintf(stcfg->scroll_text, "%s", optarg); + break; + case 'd': + sprintf(stcfg->i2c_dev_path, "%s", optarg); + break; + case 'H': + stcfg->rotate = 1; + break; + case 'N': + stcfg->need_init = 1; + break; + case 'f': + stcfg->from = atoi(optarg); + break; + case 't': + stcfg->to = atoi(optarg); + break; + default: + // Handle other parameters + break; + } + } + + if (stcfg->i2c_dev_path == NULL) + sprintf(stcfg->i2c_dev_path, "%s", I2C_DEV0_PATH); + + /* Initialize I2C bus and connect to the I2C Device */ + if (init_i2c_dev(stcfg->i2c_dev_path, SSD1306_OLED_ADDR) == 0) { + printf("Successfully connected to I2C device: %s\n", + stcfg->i2c_dev_path); + } else { + printf("Oops! There seems to be something wrong: %s\n", + stcfg->i2c_dev_path); + exit(EXIT_FAILURE); + } + + if (stcfg->disp_net_speed == 1 && + strcmp(stcfg->speed_if_name, "") != 0) { + pthread_create(&tid, NULL, (void *)pth_netspeed, + stcfg->speed_if_name); + } + + /* Run SDD1306 Initialization Sequence */ + if (stcfg->need_init == 1) display_Init_seq(); + + if (stcfg->rotate == 1) + display_rotate(); + else + display_normal(); + + /* Clear display */ + clearDisplay(); + + if (stcfg->from <= 0 || stcfg->from > 1440) { + stcfg->from = 0; + } + + if (stcfg->to <= 0 || stcfg->to > 1440) { + stcfg->to = 1440; + } + + if (stcfg->from > stcfg->to) { + int temp = stcfg->from; + stcfg->from = stcfg->to; + stcfg->to = temp; + } + + pthread_create(&tid1, NULL, (void *)pth_time_check, (void *)stcfg); + + /* Register the Alarm Handler */ + signal(SIGALRM, ALARMhandler); + signal(SIGINT, BreakDeal); + signal(SIGTERM, BreakDeal); + + // draw a single pixel + // drawPixel(0, 1, WHITE); + // Display(); + // usleep(DISPLAY_INTERVAL); + // clearDisplay(); + + // draw many lines + while (1) { + if (get_sleep_flag() == 0 && stcfg->scroll) { + testscrolltext(stcfg->scroll_text); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + + if (get_sleep_flag() == 0 && stcfg->draw_line) { + testdrawline(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + + // draw rectangles + if (get_sleep_flag() == 0 && stcfg->draw_rect) { + testdrawrect(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + + // draw multiple rectangles + if (get_sleep_flag() == 0 && stcfg->fill_rect) { + testfillrect(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + + // draw mulitple circles + if (get_sleep_flag() == 0 && stcfg->draw_circle) { + testdrawcircle(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + + // draw a white circle, 10 pixel radius + if (get_sleep_flag() == 0 && stcfg->draw_round_circle) { + testdrawroundrect(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + + // Fill the round rectangle + if (get_sleep_flag() == 0 && stcfg->fill_round_circle) { + testfillroundrect(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + + // Draw triangles + if (get_sleep_flag() == 0 && stcfg->draw_triangle) { + testdrawtriangle(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + // Fill triangles + if (get_sleep_flag() == 0 && stcfg->fill_triangle) { + testfilltriangle(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + + // Display miniature bitmap + if (get_sleep_flag() == 0 && stcfg->disp_bitmap) { + display_bitmap(); + Display(); + usleep(DISPLAY_INTERVAL); + }; + + // Display Inverted image and normalize it back + if (get_sleep_flag() == 0 && stcfg->disp_invert_normal) { + display_invert_normal(); + clearDisplay(); + usleep(DISPLAY_INTERVAL); + Display(); + } + + // Generate Signal after 20 Seconds + + // draw a bitmap icon and 'animate' movement + if (get_sleep_flag() == 0 && stcfg->draw_bitmap_eg) { + alarm(10); + flag = 0; + testdrawbitmap_eg(); + clearDisplay(); + usleep(DISPLAY_INTERVAL); + Display(); + } + + // setCursor(0,0); + setTextColor(WHITE); + + // info display + int sum = stcfg->disp_date + stcfg->disp_ip + + stcfg->disp_cpu_freq + stcfg->disp_cpu_temp + + stcfg->disp_net_speed; + if (sum == 0) { + clearDisplay(); + Display(); + usleep(DISPLAY_INTERVAL); + continue; + } + + for (int i = 1; i < stcfg->interval; i++) { + if (get_sleep_flag() == 1) { + usleep(DISPLAY_INTERVAL); + continue; + } + + if (sum == 1) { // only one item for display + if (stcfg->disp_date) testdate(CENTER, 8); + if (stcfg->disp_ip) + testip(CENTER, 8, stcfg->ip_if_name); + if (stcfg->disp_cpu_freq) + testcpufreq(CENTER, 8); + if (stcfg->disp_cpu_temp) + testcputemp(CENTER, 8); + if (stcfg->disp_net_speed) { + // read shared variables; + pthread_mutex_lock( + &__mutex_shared_variable); + { + rx_speed = __shared_rx_speed; + tx_speed = __shared_tx_speed; + } + pthread_mutex_unlock( + &__mutex_shared_variable); + + testnetspeed(SPLIT, 0, rx_speed, + tx_speed); + } + Display(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } else if (sum == 2) { // two items for display + if (stcfg->disp_date) { + testdate(CENTER, + 16 * (stcfg->disp_date - 1)); + } + if (stcfg->disp_ip) { + testip(CENTER, + 16 * (stcfg->disp_date + + stcfg->disp_ip - 1), + stcfg->ip_if_name); + } + if (stcfg->disp_cpu_freq) { + testcpufreq( + CENTER, + 16 * (stcfg->disp_date + + stcfg->disp_ip + + stcfg->disp_cpu_freq - 1)); + } + if (stcfg->disp_cpu_temp) { + testcputemp( + CENTER, + 16 * (stcfg->disp_date + + stcfg->disp_ip + + stcfg->disp_cpu_freq + + stcfg->disp_cpu_temp - 1)); + } + if (stcfg->disp_net_speed) { + // read shared variables; + pthread_mutex_lock( + &__mutex_shared_variable); + { + rx_speed = __shared_rx_speed; + tx_speed = __shared_tx_speed; + } + pthread_mutex_unlock( + &__mutex_shared_variable); + + testnetspeed( + MERGE, + 16 * (stcfg->disp_date + + stcfg->disp_ip + + stcfg->disp_cpu_freq + + stcfg->disp_cpu_temp + + stcfg->disp_net_speed - 1), + rx_speed, tx_speed); + } + Display(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } else { // more than two items for display + if (stcfg->disp_date) { + testdate(FULL, + 8 * (stcfg->disp_date - 1)); + } + if (stcfg->disp_ip) { + testip(FULL, + 8 * (stcfg->disp_date + + stcfg->disp_ip - 1), + stcfg->ip_if_name); + } + if (stcfg->disp_cpu_freq && + stcfg->disp_cpu_temp) { + testcpu(8 * (stcfg->disp_date + + stcfg->disp_ip)); + if (stcfg->disp_net_speed) { + // read shared variables; + pthread_mutex_lock( + &__mutex_shared_variable); + { + rx_speed = + __shared_rx_speed; + tx_speed = + __shared_tx_speed; + } + pthread_mutex_unlock( + &__mutex_shared_variable); + + testnetspeed( + FULL, + 8 * (stcfg->disp_date + + stcfg->disp_ip + 1 + + stcfg->disp_net_speed - + 1), + rx_speed, tx_speed); + } + } else { + if (stcfg->disp_cpu_freq) { + testcpufreq( + FULL, + 8 * (stcfg->disp_date + + stcfg->disp_ip + + stcfg->disp_cpu_freq - + 1)); + } + if (stcfg->disp_cpu_temp) { + testcputemp( + FULL, + 8 * (stcfg->disp_date + + stcfg->disp_ip + + stcfg->disp_cpu_freq + + stcfg->disp_cpu_temp - + 1)); + } + if (stcfg->disp_net_speed) { + // read shared variables; + pthread_mutex_lock( + &__mutex_shared_variable); + { + rx_speed = + __shared_rx_speed; + tx_speed = + __shared_tx_speed; + } + pthread_mutex_unlock( + &__mutex_shared_variable); + + testnetspeed( + FULL, + 8 * (stcfg->disp_date + + stcfg->disp_ip + + stcfg->disp_cpu_freq + + stcfg->disp_cpu_temp + + stcfg->disp_net_speed - + 1), + rx_speed, tx_speed); + } + } + Display(); + usleep(DISPLAY_INTERVAL); + clearDisplay(); + } + } // for + } //while + + if (stcfg->disp_net_speed == 1 && + strcmp(stcfg->speed_if_name, "") != 0) { + pthread_cancel(tid); + pthread_join(tid, NULL); + } + + if (tid1 != 0) { + pthread_cancel(tid1); + pthread_join(tid1, NULL); + } + + clearDisplay(); + Display(); + exit(EXIT_SUCCESS); +} diff --git a/luci-app-oled/luci-app-oled/src/I2C_Library/.clang-format b/luci-app-oled/luci-app-oled/src/I2C_Library/.clang-format new file mode 100644 index 000000000..5caad4065 --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/I2C_Library/.clang-format @@ -0,0 +1,183 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveBitFields: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + - Regex: '.*' + Priority: 3 + SortPriority: 0 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Auto +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +IndentWidth: 8 +TabWidth: 8 +UseCRLF: false +UseTab: Always +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE +... + diff --git a/luci-app-oled/src/I2C_Library/I2C.c b/luci-app-oled/luci-app-oled/src/I2C_Library/I2C.c similarity index 83% rename from luci-app-oled/src/I2C_Library/I2C.c rename to luci-app-oled/luci-app-oled/src/I2C_Library/I2C.c index 7177f8424..3d92f05c8 100644 --- a/luci-app-oled/src/I2C_Library/I2C.c +++ b/luci-app-oled/luci-app-oled/src/I2C_Library/I2C.c @@ -25,17 +25,18 @@ SOFTWARE. * * Created on : September 19, 2017 * Author : Vinay Divakar - * Description : This is an I2C Library for the BeagleBone that consists of the API's to support the standard + * Description : This is an I2C Library for the BeagleBone that consists of the +API's to support the standard * I2C operations. * Website : www.deeplyembedded.org */ /*Libs Includes*/ -#include -#include -#include -#include +#include #include +#include +#include +#include // heuristic to guess what version of i2c-dev.h we have: // the one installed with `apt-get install libi2c-dev` // would conflict with linux/i2c.h, while the stock @@ -52,7 +53,6 @@ typedef char i2c_char_t; /* Header Files */ #include "I2C.h" - /* Exposed objects for i2c-x */ I2C_DeviceT I2C_DEV_2; @@ -63,30 +63,26 @@ I2C_DeviceT I2C_DEV_2; * Params @i2c_dev_path: Path to the I2C device * @fd: Variable to store the file handler ****************************************************************/ -int Open_device(char *i2c_dev_path, int *fd) -{ - if((*fd = open(i2c_dev_path, O_RDWR))<0) +int Open_device(char *i2c_dev_path, int *fd) { + if ((*fd = open(i2c_dev_path, O_RDWR)) < 0) return -1; else return 0; } - /**************************************************************** * Function Name : Close_device * Description : Closes the I2C device in use * Returns : 0 on success, -1 on failure * Params : @fd: file descriptor ****************************************************************/ -int Close_device(int fd) -{ - if(close(fd) == -1) +int Close_device(int fd) { + if (close(fd) == -1) return -1; else return 0; } - /**************************************************************** * Function Name : Set_slave_addr * Description : Connect to the Slave device @@ -95,15 +91,13 @@ int Close_device(int fd) * @slave_addr: Address of the slave device to * talk to. ****************************************************************/ -int Set_slave_addr(int fd, unsigned char slave_addr) -{ - if(ioctl(fd, I2C_SLAVE, slave_addr) < 0) +int Set_slave_addr(int fd, unsigned char slave_addr) { + if (ioctl(fd, I2C_SLAVE, slave_addr) < 0) return -1; else return 0; } - /**************************************************************** * Function Name : i2c_write * Description : Write a byte on SDA @@ -111,17 +105,15 @@ int Set_slave_addr(int fd, unsigned char slave_addr) * Params @fd: File descriptor * @data: data to write on SDA ****************************************************************/ -int i2c_write(int fd, unsigned char data) -{ +int i2c_write(int fd, unsigned char data) { int ret = 0; ret = write(fd, &data, I2C_ONE_BYTE); - if((ret == -1) || (ret != 1)) + if ((ret == -1) || (ret != 1)) return -1; else - return(ret); + return (ret); } - /**************************************************************** * Function Name : i2c_read * Description : Read a byte on SDA @@ -130,18 +122,14 @@ int i2c_write(int fd, unsigned char data) * @read_data: Points to the variable that stores * the read data byte ****************************************************************/ -int i2c_read(int fd, unsigned char *read_data) -{ +int i2c_read(int fd, unsigned char *read_data) { int ret = 0; ret = read(fd, &read_data, I2C_ONE_BYTE); - if(ret == -1) - perror("I2C: Failed to read |"); - if(ret == 0) - perror("I2C: End of FILE |"); - return(ret); + if (ret == -1) perror("I2C: Failed to read |"); + if (ret == 0) perror("I2C: End of FILE |"); + return (ret); } - /**************************************************************** * Function Name : i2c_read_register * Description : Read a single register of the slave device @@ -151,23 +139,19 @@ int i2c_read(int fd, unsigned char *read_data) * @read_data: Points to the variable that stores * the read data byte ****************************************************************/ -int i2c_read_register(int fd, unsigned char read_addr, unsigned char *read_data) -{ +int i2c_read_register(int fd, unsigned char read_addr, + unsigned char *read_data) { int ret = 0; - if(i2c_write(fd, read_addr) == -1) - { + if (i2c_write(fd, read_addr) == -1) { perror("I2C: Failed to write |"); return -1; } ret = read(fd, &read_data, I2C_ONE_BYTE); - if(ret == -1) - perror("I2C: Failed to read |"); - if(ret == 0) - perror("I2C: End of FILE |"); - return(ret); + if (ret == -1) perror("I2C: Failed to read |"); + if (ret == 0) perror("I2C: End of FILE |"); + return (ret); } - /**************************************************************** * Function Name : i2c_read_registers * Description : Read a multiple registers on the slave device @@ -179,23 +163,18 @@ int i2c_read_register(int fd, unsigned char read_addr, unsigned char *read_data) * @buff_Ptr: Buffer to store the read bytes ****************************************************************/ int i2c_read_registers(int fd, int num, unsigned char starting_addr, - unsigned char *buff_Ptr) -{ + unsigned char *buff_Ptr) { int ret = 0; - if(i2c_write(fd, starting_addr) == -1) - { + if (i2c_write(fd, starting_addr) == -1) { perror("I2C: Failed to write |"); return -1; } ret = read(fd, buff_Ptr, num); - if(ret == -1) - perror("I2C: Failed to read |"); - if(ret == 0) - perror("I2C: End of FILE |"); - return(ret); + if (ret == -1) perror("I2C: Failed to read |"); + if (ret == 0) perror("I2C: End of FILE |"); + return (ret); } - /**************************************************************** * Function Name : i2c_multiple_writes * Description : Write multiple bytes on SDA @@ -205,17 +184,15 @@ int i2c_read_registers(int fd, int num, unsigned char starting_addr, * @Ptr_buff: Pointer to the buffer containing the * bytes to be written on the SDA ****************************************************************/ -int i2c_multiple_writes(int fd, int num, unsigned char *Ptr_buff) -{ +int i2c_multiple_writes(int fd, int num, unsigned char *Ptr_buff) { int ret = 0; ret = write(fd, Ptr_buff, num); - if((ret == -1) || (ret != num)) + if ((ret == -1) || (ret != num)) return -1; else - return(ret); + return (ret); } - /**************************************************************** * Function Name : i2c_write_register * Description : Write a control byte or byte to a register @@ -226,20 +203,19 @@ int i2c_multiple_writes(int fd, int num, unsigned char *Ptr_buff) * @val: Command or value to be written in the * addressed register ****************************************************************/ -int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, unsigned char val) -{ +int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, + unsigned char val) { unsigned char buff[2]; int ret = 0; buff[0] = reg_addr_or_cntrl; buff[1] = val; ret = write(fd, buff, I2C_TWO_BYTES); - if((ret == -1) || (ret != I2C_TWO_BYTES)) + if ((ret == -1) || (ret != I2C_TWO_BYTES)) return -1; else - return(ret); + return (ret); } - /**************************************************************** * Function Name : config_i2c_struct * Description : Initialize the I2C device structure @@ -248,14 +224,13 @@ int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, unsigned char va * @slave_addr: Slave device address * @i2c_dev: Pointer to the device structure ****************************************************************/ -void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, I2C_DevicePtr i2c_dev) -{ +void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, + I2C_DevicePtr i2c_dev) { i2c_dev->i2c_dev_path = i2c_dev_path; i2c_dev->fd_i2c = 0; i2c_dev->i2c_slave_addr = slave_addr; } - /**************************************************************** * Function Name : init_i2c_dev * Description : Connect the i2c bus to the slave device @@ -263,16 +238,13 @@ void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, I2C_DeviceP * Params @i2c_path: the path to the device * @slave_addr: Slave device address ****************************************************************/ -int init_i2c_dev(const char* i2c_path, unsigned char slave_address) -{ - config_i2c_struct((char*)i2c_path, slave_address, &I2C_DEV_2); - if(Open_device(I2C_DEV_2.i2c_dev_path, &I2C_DEV_2.fd_i2c) == -1) - { +int init_i2c_dev(const char *i2c_path, unsigned char slave_address) { + config_i2c_struct((char *)i2c_path, slave_address, &I2C_DEV_2); + if (Open_device(I2C_DEV_2.i2c_dev_path, &I2C_DEV_2.fd_i2c) == -1) { perror("I2C: Failed to open device |"); return -1; } - if(Set_slave_addr(I2C_DEV_2.fd_i2c, I2C_DEV_2.i2c_slave_addr) == -1) - { + if (Set_slave_addr(I2C_DEV_2.fd_i2c, I2C_DEV_2.i2c_slave_addr) == -1) { perror("I2C: Failed to connect to slave device |"); return -1; } diff --git a/luci-app-oled/src/I2C_Library/I2C.h b/luci-app-oled/luci-app-oled/src/I2C_Library/I2C.h similarity index 76% rename from luci-app-oled/src/I2C_Library/I2C.h rename to luci-app-oled/luci-app-oled/src/I2C_Library/I2C.h index ffcc45933..b14cfa7d5 100644 --- a/luci-app-oled/src/I2C_Library/I2C.h +++ b/luci-app-oled/luci-app-oled/src/I2C_Library/I2C.h @@ -26,29 +26,29 @@ SOFTWARE. * Created on : Sep 4, 2017 * Author : Vinay Divakar * Website : www.deeplyembedded.org - */ + */ #ifndef I2C_H_ #define I2C_H_ -#include +#include /* No. of bytes per transaction */ -#define I2C_ONE_BYTE 1 -#define I2C_TWO_BYTES 2 -#define I2C_THREE_BYTES 3 +#define I2C_ONE_BYTE 1 +#define I2C_TWO_BYTES 2 +#define I2C_THREE_BYTES 3 /*Definitions specific to i2c-x */ -#define I2C_DEV0_PATH "/dev/i2c-0" -#define I2C_DEV1_PATH "/dev/i2c-1" -#define I2C_DEV2_PATH "/dev/i2c-2" +#define I2C_DEV0_PATH "/dev/i2c-0" +#define I2C_DEV1_PATH "/dev/i2c-1" +#define I2C_DEV2_PATH "/dev/i2c-2" /*I2C device configuration structure*/ -typedef struct{ - char* i2c_dev_path; +typedef struct { + char *i2c_dev_path; int fd_i2c; unsigned char i2c_slave_addr; -}I2C_DeviceT, *I2C_DevicePtr; +} I2C_DeviceT, *I2C_DevicePtr; /* Exposed Generic I2C Functions */ extern int Open_device(char *i2c_dev_path, int *fd); @@ -56,14 +56,17 @@ extern int Close_device(int fd); extern int Set_slave_addr(int fd, unsigned char slave_addr); extern int i2c_write(int fd, unsigned char data); extern int i2c_read(int fd, unsigned char *read_data); -extern int i2c_read_register(int fd, unsigned char read_addr, unsigned char *read_data); +extern int i2c_read_register(int fd, unsigned char read_addr, + unsigned char *read_data); extern int i2c_read_registers(int fd, int num, unsigned char starting_addr, - unsigned char *buff_Ptr); -extern void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, I2C_DevicePtr i2c_dev); + unsigned char *buff_Ptr); +extern void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, + I2C_DevicePtr i2c_dev); extern int i2c_multiple_writes(int fd, int num, unsigned char *Ptr_buff); -extern int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, unsigned char val); +extern int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, + unsigned char val); /* Exposed I2C-x Specific Functions */ -extern int init_i2c_dev(const char* i2c_path, unsigned char slave_address); +extern int init_i2c_dev(const char *i2c_path, unsigned char slave_address); #endif /* I2C_H_ */ diff --git a/luci-app-oled/src/LICENSE b/luci-app-oled/luci-app-oled/src/LICENSE similarity index 100% rename from luci-app-oled/src/LICENSE rename to luci-app-oled/luci-app-oled/src/LICENSE diff --git a/luci-app-oled/luci-app-oled/src/Makefile b/luci-app-oled/luci-app-oled/src/Makefile new file mode 100644 index 000000000..9038825c8 --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/Makefile @@ -0,0 +1,30 @@ +ifndef CC +CC = gcc +endif +ifndef LD +LD = ld +endif + +SOURCES = SSD1306_OLED_Library/SSD1306_OLED.c Example_Code/main.c Example_Code/example_app.c I2C_Library/I2C.c +OBJS := $(SOURCES:.c=.o) +CPPFLAGS := -I SSD1306_OLED_Library -I I2C_Library +ifndef CFLAGS +CFLAGS := -O2 +endif +LDFLAGS := -lpthread -lconfig + +oled: $(OBJS) + $(CC) $^ -o $@ $(LDFLAGS) + +ssd1306: $(OBJS) + $(CC) $^ -o $@ $(LDFLAGS) --static + strip $@ + +clean: + rm -rf oled ssd1306 $(OBJS) + +compile: oled + +install: compile + mkdir -p $(DESTDIR)/usr/bin + cp oled $(DESTDIR)/usr/bin/oled diff --git a/luci-app-oled/src/README.md b/luci-app-oled/luci-app-oled/src/README.md similarity index 100% rename from luci-app-oled/src/README.md rename to luci-app-oled/luci-app-oled/src/README.md diff --git a/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/.clang-format b/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/.clang-format new file mode 100644 index 000000000..5caad4065 --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/.clang-format @@ -0,0 +1,183 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveBitFields: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: WithoutElse +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^' + Priority: 2 + SortPriority: 0 + - Regex: '^<.*\.h>' + Priority: 1 + SortPriority: 0 + - Regex: '^<.*' + Priority: 2 + SortPriority: 0 + - Regex: '.*' + Priority: 3 + SortPriority: 0 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Auto +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +IndentWidth: 8 +TabWidth: 8 +UseCRLF: false +UseTab: Always +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE +... + diff --git a/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c b/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c new file mode 100644 index 000000000..b24480d76 --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c @@ -0,0 +1,2376 @@ +/* + * MIT License + +Copyright (c) 2017 DeeplyEmbedded + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * SSD1306_OLED.c + * + * Created on : Sep 26, 2017 + * Author : Vinay Divakar + * Description : SSD1306 OLED Driver, Graphics API's. + * Website : www.deeplyembedded.org + */ + +/* Lib Includes */ +#include "SSD1306_OLED.h" + +#include +#include +#include +#include +#include + +#include "I2C.h" +#include "gfxfont.h" + +/* Enable or Disable DEBUG Prints */ +//#define SSD1306_DBG + +/* MACROS */ +#define SWAP(x, y) \ + { \ + short temp; \ + temp = x; \ + x = y; \ + y = temp; \ + } +#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) +#define pgm_read_word(addr) (*(const unsigned long *)(addr)) +#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) +#define pgm_read_pointer(addr) ((void *)pgm_read_word(addr)) + +/* static Variables */ +static unsigned char _rotation = 0, textsize = 0; +static short _width = SSD1306_LCDWIDTH; +static short _height = SSD1306_LCDHEIGHT; +static short cursor_x = 0, cursor_y = 0, textcolor = 0, textbgcolor = 0; +static bool _cp437 = false, wrap = true; + +/* static struct objects */ +static GFXfontPtr gfxFont; + +/* Externs - I2C.c */ +extern I2C_DeviceT I2C_DEV_2; + +/* Chunk Buffer */ +static unsigned char chunk[17] = {0}; + +/* Memory buffer for displaying data on LCD - This is an Apple - Fruit */ +static unsigned char screen[DISPLAY_BUFF_SIZE] = {0}; + +/* Static Functions */ +static void transfer(); +static void drawFastVLine(short x, short y, short h, short color); +static void writeFastVLine(short x, short y, short h, short color); +static void drawFastHLine(short x, short y, short w, short color); +static void writeFastHLine(short x, short y, short w, short color); +static short print(const unsigned char *buffer, short size); + +// Standard ASCII 5x7 font +static const unsigned char ssd1306_font5x7[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, // space + 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x1C, + 0x3E, 0x7C, 0x3E, 0x1C, 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x1C, 0x57, + 0x7D, 0x57, 0x1C, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00, 0x18, 0x3C, + 0x18, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x18, 0x24, 0x18, + 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x30, 0x48, 0x3A, 0x06, 0x0E, + 0x26, 0x29, 0x79, 0x29, 0x26, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x40, + 0x7F, 0x05, 0x25, 0x3F, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x7F, 0x3E, + 0x1C, 0x1C, 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x14, 0x22, 0x7F, + 0x22, 0x14, 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x06, 0x09, 0x7F, 0x01, + 0x7F, 0x00, 0x66, 0x89, 0x95, 0x6A, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x08, 0x04, 0x7E, 0x04, 0x08, // up INDEX 24 + 0x10, 0x20, 0x7E, 0x20, 0x10, // down INDEX 25 + 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x1E, + 0x10, 0x10, 0x10, 0x10, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x30, 0x38, + 0x3E, 0x38, 0x30, 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, + 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x24, 0x2A, 0x7F, 0x2A, 0x12, + 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, + 0x08, 0x07, 0x03, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x41, + 0x22, 0x1C, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08, 0x08, 0x3E, + 0x08, 0x08, 0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, + 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x72, + 0x49, 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x18, 0x14, + 0x12, 0x7F, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, + 0x49, 0x31, 0x41, 0x21, 0x11, 0x09, 0x07, 0x36, 0x49, 0x49, 0x49, + 0x36, 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x00, 0x41, 0x22, 0x14, 0x08, 0x02, 0x01, + 0x59, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x7C, 0x12, 0x11, + 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E, 0x41, 0x41, 0x41, + 0x22, // C + 0x7F, 0x41, 0x41, 0x41, 0x3E, // D + 0x7F, 0x49, 0x49, 0x49, 0x41, // E + 0x7F, 0x09, 0x09, 0x09, 0x01, // F + 0x3E, 0x41, 0x41, 0x51, 0x73, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, + 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x7F, 0x08, + 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x02, 0x1C, + 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E, 0x41, 0x41, 0x41, + 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51, 0x21, 0x5E, + 0x7F, 0x09, 0x19, 0x29, 0x46, 0x26, 0x49, 0x49, 0x49, 0x32, 0x03, + 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20, + 0x40, 0x20, 0x1F, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, + 0x14, 0x63, 0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, + 0x43, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x00, 0x41, 0x41, 0x41, 0x7F, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, + 0x54, 0x78, 0x40, 0x7F, 0x28, 0x44, 0x44, 0x38, 0x38, 0x44, 0x44, + 0x44, 0x28, 0x38, 0x44, 0x44, 0x28, 0x7F, 0x38, 0x54, 0x54, 0x54, + 0x18, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x18, 0xA4, 0xA4, 0x9C, 0x78, + 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D, 0x40, 0x00, 0x20, + 0x40, 0x40, 0x3D, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x41, + 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08, 0x04, + 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xFC, 0x18, 0x24, 0x24, + 0x18, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x7C, 0x08, 0x04, 0x04, 0x08, + 0x48, 0x54, 0x54, 0x54, 0x24, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x3C, + 0x40, 0x40, 0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, + 0x30, 0x40, 0x3C, 0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, + 0x90, 0x7C, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, + 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x1E, + 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40, 0x20, 0x7A, 0x38, 0x54, + 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41, 0x22, 0x54, 0x54, + 0x78, 0x42, // a-umlaut + 0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, + 0x1E, 0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, + 0x54, 0x54, 0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, + 0x7C, 0x41, 0x00, 0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, + 0x40, 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut + 0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, + 0x54, 0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, + 0x49, 0x49, 0x32, 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut + 0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, + 0x42, 0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x3D, 0x42, + 0x42, 0x42, 0x3D, // O-umlaut + 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, + 0x7E, 0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, + 0x29, 0xF6, 0x20, 0xC0, 0x88, 0x7E, 0x09, 0x03, 0x20, 0x54, 0x54, + 0x79, 0x41, 0x00, 0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, + 0x32, 0x38, 0x40, 0x40, 0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, + 0x7D, 0x0D, 0x19, 0x31, 0x7D, 0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, + 0x29, 0x29, 0x29, 0x26, 0x30, 0x48, 0x4D, 0x40, 0x20, 0x38, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x2F, 0x10, 0xC8, + 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00, 0x00, 0x7B, 0x00, + 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A, 0x14, 0x08, + 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code + 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block + 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block + 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x14, + 0x14, 0x14, 0xFF, 0x00, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x10, 0x10, + 0xF0, 0x10, 0xF0, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x14, 0x14, 0xF7, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x14, 0x14, 0xF4, 0x04, + 0xFC, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0x1F, 0x00, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, + 0x10, 0xF0, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, + 0x14, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x10, 0x17, + 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, + 0x14, 0xF4, 0x04, 0xF4, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, + 0x17, 0x14, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0xF4, + 0x14, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, + 0x00, 0x00, 0x00, 0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, + 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, + 0x14, 0xFF, 0x14, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, + 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, + 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44, 0x38, 0x44, 0xFC, + 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta + 0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, + 0x55, 0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, + 0x20, 0x1E, 0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, + 0xA5, 0x99, 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, + 0x4C, 0x30, 0x4A, 0x4D, 0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, + 0xBC, 0x62, 0x5A, 0x46, 0x3D, 0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, + 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x44, 0x44, + 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44, 0x40, 0x40, 0x44, 0x4A, + 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0, 0x80, 0xFF, 0x00, + 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36, 0x24, 0x36, + 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F, + 0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, + 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP +}; + +/**************************************************************** + * Function Name : clearDisplay + * Description : Clear the display memory buffer + * Returns : NONE. + * Params : NONE. + ****************************************************************/ +void clearDisplay() { memset(screen, 0x00, DISPLAY_BUFF_SIZE); } + +/**************************************************************** + * Function Name : display_Init_seq + * Description : Performs SSD1306 OLED Initialization Sequence + * Returns : NONE. + * Params : NONE. + ****************************************************************/ +void display_Init_seq() { + /* Add the reset code, If needed */ + + /* Send display OFF command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_DISPLAY_OFF) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display OFF Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display OFF Command Failed\r\n"); +#endif + exit(1); + } + + /* Set display clock frequency */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_DISP_CLK) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display CLK Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display CLK Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display CLK command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_DISPCLK_DIV) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display CLK Command Parameter Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display CLK Command Parameter Failed\r\n"); +#endif + exit(1); + } + + /* Set display multiplex */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_MULTIPLEX) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display MULT Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display MULT Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display MULT command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_MULT_DAT) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display MULT Command Parameter Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display MULT Command Parameter Failed\r\n"); +#endif + exit(1); + } + + /* Set display OFFSET */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_DISP_OFFSET) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display OFFSET Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display OFFSET Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display OFFSET command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_DISP_OFFSET_VAL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display OFFSET Command Parameter Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display OFFSET Command Parameter Failed\r\n"); +#endif + exit(1); + } + + /* Set display START LINE - Check this command if something weird + * happens */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_DISP_START_LINE) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display START LINE Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display START LINE Command Failed\r\n"); +#endif + exit(1); + } + + /* Enable CHARGEPUMP*/ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_CONFIG_CHARGE_PUMP) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display CHARGEPUMP Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display CHARGEPUMP Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display CHARGEPUMP command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_CHARGE_PUMP_EN) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display CHARGEPUMP Command Parameter Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display CHARGEPUMP Command Parameter Failed\r\n"); +#endif + exit(1); + } + + /* Set display MEMORYMODE */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_MEM_ADDR_MODE) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display MEMORYMODE Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display MEMORYMODE Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display HORIZONTAL MEMORY ADDR MODE command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_HOR_MM) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf( + "Display HORIZONTAL MEMORY ADDR MODE Command Parameter " + "Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf( + "Display HORIZONTAL MEMORY ADDR MODE Command Parameter " + "Failed\r\n"); +#endif + exit(1); + } + + /* Set display COM */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_COMPINS) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display COM Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display COM Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display COM command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_CONFIG_COM_PINS) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display COM Command Parameter Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display COM Command Parameter Failed\r\n"); +#endif + exit(1); + } + + /* Set display CONTRAST */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_CONTRAST) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display CONTRAST Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display CONTRAST Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display CONTRAST command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_CONTRAST_VAL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display CONTRAST Command Parameter Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display CONTRAST Command Parameter Failed\r\n"); +#endif + exit(1); + } + + /* Set display PRECHARGE */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_PRECHARGE) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display PRECHARGE Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display PRECHARGE Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display PRECHARGE command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_PRECHARGE_VAL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display PRECHARGE Command Parameter Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display PRECHARGE Command Parameter Failed\r\n"); +#endif + exit(1); + } + + /* Set display VCOMH */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_VCOMDETECT) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display VCOMH Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display VCOMH Command Failed\r\n"); +#endif + exit(1); + } + + /* Send display VCOMH command parameter */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_VCOMH_VAL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display VCOMH Command Parameter Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display VCOMH Command Parameter Failed\r\n"); +#endif + exit(1); + } + + /* Set display ALL-ON */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_DISPLAYALLON_RESUME) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display ALL-ON Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display ALL-ON Command Failed\r\n"); +#endif + exit(1); + } + + /* Set display to NORMAL-DISPLAY */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_NORMAL_DISPLAY) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display NORMAL-DISPLAY Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display NORMAL-DISPLAY Command Failed\r\n"); +#endif + exit(1); + } + + /* Set display to DEACTIVATE_SCROLL */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_DEACTIVATE_SCROLL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display DEACTIVATE_SCROLL Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display DEACTIVATE_SCROLL Command Failed\r\n"); +#endif + exit(1); + } + + /* Set display to TURN-ON */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_DISPLAYON) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display TURN-ON Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display TURN-ON Command Failed\r\n"); +#endif + exit(1); + } +} + +/**************************************************************** + * Function Name : display_normal + * Description : Normal display + * Returns : NONE. + * Params : NONE. + ****************************************************************/ +void display_normal() { + /* Set display SEG_REMAP */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SEG_REMAP) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display SEG_REMAP Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display SEG_REMAP Command Failed\r\n"); +#endif + exit(1); + } + + /* Set display COMSCANDEC */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_COMSCANDEC) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display DIR Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display DIR Command Failed\r\n"); +#endif + exit(1); + } +} + +/**************************************************************** + * Function Name : display_rotate + * Description : 180 degree rotation + * Returns : NONE. + * Params : NONE. + ****************************************************************/ +void display_rotate() { + /* Set display SEG_REMAP1 */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SEG_REMAP1) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display SEG_REMAP Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display SEG_REMAP Command Failed\r\n"); +#endif + exit(1); + } + + /* Set display COMSCANDEC1 */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_COMSCANDEC1) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display DIR Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display DIR Command Failed\r\n"); +#endif + exit(1); + } +} + +/**************************************************************** + * Function Name : transfer + * Description : Transfer the frame buffer onto the display + * Returns : NONE. + * Params : NONE. + ****************************************************************/ +void transfer() { + short loop_1 = 0, loop_2 = 0; + short index = 0x00; + for (loop_1 = 0; loop_1 < 1024; loop_1++) { + chunk[0] = 0x40; + for (loop_2 = 1; loop_2 < 17; loop_2++) + chunk[loop_2] = screen[index++]; + if (i2c_multiple_writes(I2C_DEV_2.fd_i2c, 17, chunk) == 17) { +#ifdef SSD1306_DBG + printf("Chunk written to RAM - Completed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Chunk written to RAM - Failed\r\n"); +#endif + exit(1); + } + + memset(chunk, 0x00, 17); + if (index == 1024) break; + } +} + +/**************************************************************** + * Function Name : Display + * Description : 1. Resets the column and page addresses. + * 2. Displays the contents of the memory buffer. + * Returns : NONE. + * Params : NONE. + * Note : Each new form can be preceded by a clearDisplay. + ****************************************************************/ +void Display() { + Init_Col_PG_addrs(SSD1306_COL_START_ADDR, SSD1306_COL_END_ADDR, + SSD1306_PG_START_ADDR, SSD1306_PG_END_ADDR); + transfer(); +} + +/**************************************************************** + * Function Name : Init_Col_PG_addrs + * Description : Sets the column and page, start and + * end addresses. + * Returns : NONE. + * Params : @col_start_addr: Column start address + * @col_end_addr: Column end address + * @pg_start_addr: Page start address + * @pg_end_addr: Page end address + ****************************************************************/ +void Init_Col_PG_addrs(unsigned char col_start_addr, unsigned char col_end_addr, + unsigned char pg_start_addr, unsigned char pg_end_addr) { + /* Send COLMN address setting command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_COL_ADDR) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display COLMN Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display COLMN Command Failed\r\n"); +#endif + exit(1); + } + + /* Set COLMN start address */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + col_start_addr) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display COLMN Start Address param Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display COLMN Start Address param Failed\r\n"); +#endif + exit(1); + } + + /* Set COLMN end address */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + col_end_addr) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display COLMN End Address param Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display COLMN End Address param Failed\r\n"); +#endif + exit(1); + } + + /* Send PAGE address setting command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_PAGEADDR) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display PAGE Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display PAGE Command Failed\r\n"); +#endif + exit(1); + } + + /* Set PAGE start address */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + pg_start_addr) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display PAGE Start Address param Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display PAGE Start Address param Failed\r\n"); +#endif + exit(1); + } + + /* Set PAGE end address */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + pg_end_addr) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display PAGE End Address param Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display PAGE End Address param Failed\r\n"); +#endif + exit(1); + } +} + +/**************************************************************** + * Function Name : setRotation + * Description : Set the display rotation + * Returns : NONE. + * Params : @x: Display rotation parameter + ****************************************************************/ +void setRotation(unsigned char x) { + _rotation = x & 3; + switch (_rotation) { + case 0: + case 2: + _width = SSD1306_LCDWIDTH; + _height = SSD1306_LCDHEIGHT; + break; + case 1: + case 3: + _width = SSD1306_LCDHEIGHT; + _height = SSD1306_LCDWIDTH; + break; + } +} + +/**************************************************************** + * Function Name : startscrollright + * Description : Activate a right handed scroll for rows start + * through stop + * Returns : NONE. + * Params : @start: Start location + * @stop: Stop location + * HINT. : the display is 16 rows tall. To scroll the whole + * display, run: display.scrollright(0x00, 0x0F) + ****************************************************************/ +void startscrollright(unsigned char start, unsigned char stop) { + /* Send SCROLL horizontal right command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_RIGHT_HORIZONTAL_SCROLL) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display HORIZONTAL SCROLL RIGHT Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display HORIZONTAL SCROLL RIGHT Command Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_1 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_1 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, start) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_2 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_2 Passed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_3 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_3 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, stop) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_4 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_4 Passed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_5 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_5 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0xFF) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_6 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_6 Passed\r\n"); +#endif + exit(1); + } + /* Send SCROLL Activate command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_ACTIVATE_SCROLL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("SCROLL Activate Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("SCROLL Activate Command Failed\r\n"); +#endif + exit(1); + } +} + +/**************************************************************** + * Function Name : startscrollleft + * Description : Activate a left handed scroll for rows start + * through stop + * Returns : NONE. + * Params : @start: Start location + * @stop: Stop location + * HINT. : the display is 16 rows tall. To scroll the whole + * display, run: display.scrollright(0x00, 0x0F) + ****************************************************************/ +void startscrollleft(unsigned char start, unsigned char stop) { + /* Send SCROLL horizontal left command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_LEFT_HORIZONTAL_SCROLL) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display HORIZONTAL SCROLL LEFT Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display HORIZONTAL SCROLL LEFT Command Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_1 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_1 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, start) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_2 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_2 Passed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_3 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_3 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, stop) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_4 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_4 Passed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_5 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_5 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0xFF) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("HORI_SR Param_6 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("HORI_SR Param_6 Passed\r\n"); +#endif + exit(1); + } + /* Send SCROLL Activate command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_ACTIVATE_SCROLL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("SCROLL Activate Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("SCROLL Activate Command Failed\r\n"); +#endif + exit(1); + } +} + +/**************************************************************** + * Function Name : startscrolldiagright + * Description : Activate a diagonal scroll for rows start + * through stop + * Returns : NONE. + * Params : @start: Start location + * @stop: Stop location + * HINT. : the display is 16 rows tall. To scroll the whole + * display, run: display.scrollright(0x00, 0x0F) + ****************************************************************/ +void startscrolldiagright(unsigned char start, unsigned char stop) { + /* Send SCROLL diagonal right command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_VERTICAL_SCROLL_AREA) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display DIAGONAL SCROLL RIGHT Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display DIAGONAL SCROLL RIGHT Command Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_1 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_1 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_LCDHEIGHT) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_2 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_2 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Cmd Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Cmd Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_3 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_3 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, start) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_4 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_4 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_5 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_5 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, stop) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_6 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_6 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x01) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_5 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_5 Failed\r\n"); +#endif + exit(1); + } + + /* Send SCROLL Activate command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_ACTIVATE_SCROLL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("SCROLL Activate Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("SCROLL Activate Command Failed\r\n"); +#endif + exit(1); + } +} + +/**************************************************************** + * Function Name : startscrolldiagleft + * Description : Activate a diagonal scroll for rows start + * through stop + * Returns : NONE. + * Params : @start: Start location + * @stop: Stop location + * HINT. : the display is 16 rows tall. To scroll the whole + * display, run: display.scrollright(0x00, 0x0F) + ****************************************************************/ +void startscrolldiagleft(unsigned char start, unsigned char stop) { + /* Send SCROLL diagonal right command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_SET_VERTICAL_SCROLL_AREA) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Display DIAGONAL SCROLL RIGHT Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Display DIAGONAL SCROLL RIGHT Command Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_1 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_1 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_LCDHEIGHT) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_2 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_2 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("Cmd Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("Cmd Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_3 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_3 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, start) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_4 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_4 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_5 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_5 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, stop) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_6 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_6 Failed\r\n"); +#endif + exit(1); + } + + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x01) == + I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_5 Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("DIAG_SR Param_5 Failed\r\n"); +#endif + exit(1); + } + + /* Send SCROLL Activate command */ + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_ACTIVATE_SCROLL) == I2C_TWO_BYTES) { +#ifdef SSD1306_DBG + printf("SCROLL Activate Command Passed\r\n"); +#endif + } else { +#ifdef SSD1306_DBG + printf("SCROLL Activate Command Failed\r\n"); +#endif + exit(1); + } +} + +/**************************************************************** + * Function Name : stopscroll + * Description : Stop scrolling + * Returns : NONE. + * Params : NONE. + ****************************************************************/ +void stopscroll() { + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_DEACTIVATE_SCROLL) == I2C_TWO_BYTES) { + printf("De-activate SCROLL Command Passed\r\n"); + } else { + printf("De-activate SCROLL Command Passed Failed\r\n"); + exit(1); + } +} + +/**************************************************************** + * Function Name : invertDisplay + * Description : Invert or Normalize the display + * Returns : NONE. + * Params : @i: 0x00 to Normal and 0x01 for Inverting + ****************************************************************/ +void invertDisplay(unsigned char i) { + if (i) { + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_INVERTDISPLAY) == + I2C_TWO_BYTES) { + printf("Display Inverted - Passed\r\n"); + } else { + printf("Display Inverted - Failed\r\n"); + exit(1); + } + } else { + if (i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, + SSD1306_NORMAL_DISPLAY) == + I2C_TWO_BYTES) { + printf("Display Normal - Passed\r\n"); + } else { + printf("Display Normal - Failed\r\n"); + exit(1); + } + } +} + +/**************************************************************** + * Function Name : drawPixel + * Description : Draw a pixel + * Returns : -1 on error and 0 on success + * Params : @x: X - Co-ordinate + * @y: Y - Co-ordinate + * @color: Color + ****************************************************************/ +signed char drawPixel(short x, short y, short color) { + /* Return if co-ordinates are out of display dimension's range */ + if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return -1; + switch (_rotation) { + case 1: + SWAP(x, y); + x = _width - x - 1; + break; + case 2: + x = _width - x - 1; + y = _height - y - 1; + break; + case 3: + SWAP(x, y); + y = _height - y - 1; + break; + } + + /* x is the column */ + switch (color) { + case WHITE: + screen[x + (y / 8) * SSD1306_LCDWIDTH] |= + (1 << (y & 7)); + break; + case BLACK: + screen[x + (y / 8) * SSD1306_LCDWIDTH] &= + ~(1 << (y & 7)); + break; + case INVERSE: + screen[x + (y / 8) * SSD1306_LCDWIDTH] ^= + (1 << (y & 7)); + break; + } + return 0; +} + +/**************************************************************** + * Function Name : writeLine + * Description : Bresenham's algorithm + * Returns : NONE + * Params : @x0: X0 Co-ordinate + * @y0: Y0 Co-ordinate + * @x1: X1 Co-ordinate + * @y1: Y1 Co-ordinate + * @color: Pixel color + ****************************************************************/ +void writeLine(short x0, short y0, short x1, short y1, short color) { + short steep = 0, dx = 0, dy = 0, err = 0, ystep = 0; + steep = abs(y1 - y0) > abs(x1 - x0); + if (steep) { + SWAP(x0, y0); + SWAP(x1, y1); + } + + if (x0 > x1) { + SWAP(x0, x1); + SWAP(y0, y1); + } + dx = x1 - x0; + dy = abs(y1 - y0); + + err = dx / 2; + + if (y0 < y1) { + ystep = 1; + } else { + ystep = -1; + } + + for (; x0 <= x1; x0++) { + if (steep) { + drawPixel(y0, x0, color); + } else { + drawPixel(x0, y0, color); + } + err -= dy; + if (err < 0) { + y0 += ystep; + err += dx; + } + } +} + +/* (x,y) is topmost point; if unsure, calling function +should sort endpoints or call writeLine() instead */ +void drawFastVLine(short x, short y, short h, short color) { + // startWrite(); + writeLine(x, y, x, y + h - 1, color); + // endWrite(); +} + +/* (x,y) is topmost point; if unsure, calling function +should sort endpoints or call writeLine() instead */ +void writeFastVLine(short x, short y, short h, short color) { + drawFastVLine(x, y, h, color); +} + +/* (x,y) is leftmost point; if unsure, calling function + should sort endpoints or call writeLine() instead */ +void drawFastHLine(short x, short y, short w, short color) { + // startWrite(); + writeLine(x, y, x + w - 1, y, color); + // endWrite(); +} + +// (x,y) is leftmost point; if unsure, calling function +// should sort endpoints or call writeLine() instead +void writeFastHLine(short x, short y, short w, short color) { + drawFastHLine(x, y, w, color); +} + +/**************************************************************** + * Function Name : drawCircleHelper + * Description : Draw a.... + * Returns : NONE + * Params : @x: X Co-ordinate + * @y: Y Co-ordinate + * @w: Width + * @h: height + * @r: Corner radius + * @color: Pixel color + ****************************************************************/ +void drawCircleHelper(short x0, short y0, short r, unsigned char cornername, + short color) { + short f = 1 - r; + short ddF_x = 1; + short ddF_y = -2 * r; + short x = 0; + short y = r; + + while (x < y) { + if (f >= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + if (cornername & 0x4) { + drawPixel(x0 + x, y0 + y, color); + drawPixel(x0 + y, y0 + x, color); + } + if (cornername & 0x2) { + drawPixel(x0 + x, y0 - y, color); + drawPixel(x0 + y, y0 - x, color); + } + if (cornername & 0x8) { + drawPixel(x0 - y, y0 + x, color); + drawPixel(x0 - x, y0 + y, color); + } + if (cornername & 0x1) { + drawPixel(x0 - y, y0 - x, color); + drawPixel(x0 - x, y0 - y, color); + } + } +} + +/**************************************************************** + * Function Name : drawLine + * Description : Draw line between two points + * Returns : NONE + * Params : @x0: X0 Starting X Co-ordinate + * @y0: Y0 Starting Y Co-ordinate + * @x1: X1 Ending X Co-ordinate + * @y1: Y1 Ending Y Co-ordinate + * @color: Pixel color + ****************************************************************/ +void drawLine(short x0, short y0, short x1, short y1, short color) { + if (x0 == x1) { + if (y0 > y1) SWAP(y0, y1); + drawFastVLine(x0, y0, y1 - y0 + 1, color); + } else if (y0 == y1) { + if (x0 > x1) SWAP(x0, x1); + drawFastHLine(x0, y0, x1 - x0 + 1, color); + } else { + // startWrite(); + writeLine(x0, y0, x1, y1, color); + // endWrite(); + } +} + +/**************************************************************** + * Function Name : drawRect + * Description : Draw a rectangle + * Returns : NONE + * Params : @x: Corner X Co-ordinate + * @y: Corner Y Co-ordinate + * @w: Width in pixels + * @h: Height in pixels + * @color: Pixel color + ****************************************************************/ +void drawRect(short x, short y, short w, short h, short color) { + // startWrite(); + writeFastHLine(x, y, w, color); + writeFastHLine(x, y + h - 1, w, color); + writeFastVLine(x, y, h, color); + writeFastVLine(x + w - 1, y, h, color); + // endWrite(); +} + +/**************************************************************** + * Function Name : fillRect + * Description : Fill the rectangle + * Returns : NONE + * Params : @x: Starting X Co-ordinate + * @y: Starting Y Co-ordinate + * @w: Width in pixels + * @h: Height in pixels + * @color: Pixel color + ****************************************************************/ +void fillRect(short x, short y, short w, short h, short color) { + short i = 0; + // startWrite(); + for (i = x; i < x + w; i++) { + writeFastVLine(i, y, h, color); + } + // endWrite(); +} + +/**************************************************************** + * Function Name : drawCircle + * Description : Draw a circle + * Returns : NONE + * Params : @x: Center X Co-ordinate + * @y: Center Y Co-ordinate + * @r: Radius in pixels + * @color: Pixel color + ****************************************************************/ +void drawCircle(short x0, short y0, short r, short color) { + short f = 1 - r; + short ddF_x = 1; + short ddF_y = -2 * r; + short x = 0; + short y = r; + + // startWrite(); + drawPixel(x0, y0 + r, color); + drawPixel(x0, y0 - r, color); + drawPixel(x0 + r, y0, color); + drawPixel(x0 - r, y0, color); + + while (x < y) { + if (f >= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + drawPixel(x0 + x, y0 + y, color); + drawPixel(x0 - x, y0 + y, color); + drawPixel(x0 + x, y0 - y, color); + drawPixel(x0 - x, y0 - y, color); + drawPixel(x0 + y, y0 + x, color); + drawPixel(x0 - y, y0 + x, color); + drawPixel(x0 + y, y0 - x, color); + drawPixel(x0 - y, y0 - x, color); + } + // endWrite(); +} + +/**************************************************************** + * Function Name : fillCircleHelper + * Description : Used to do circles and roundrects + * Returns : NONE + * Params : @x: Center X Co-ordinate + * @y: Center Y Co-ordinate + * @r: Radius in pixels + * @cornername: Corner radius in pixels + * @color: Pixel color + ****************************************************************/ +void fillCircleHelper(short x0, short y0, short r, unsigned char cornername, + short delta, short color) { + short f = 1 - r; + short ddF_x = 1; + short ddF_y = -2 * r; + short x = 0; + short y = r; + + while (x < y) { + if (f >= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + if (cornername & 0x1) { + writeFastVLine(x0 + x, y0 - y, 2 * y + 1 + delta, + color); + writeFastVLine(x0 + y, y0 - x, 2 * x + 1 + delta, + color); + } + if (cornername & 0x2) { + writeFastVLine(x0 - x, y0 - y, 2 * y + 1 + delta, + color); + writeFastVLine(x0 - y, y0 - x, 2 * x + 1 + delta, + color); + } + } +} + +/**************************************************************** + * Function Name : fillCircle + * Description : Fill the circle + * Returns : NONE + * Params : @x0: Center X Co-ordinate + * @y0: Center Y Co-ordinate + * @r: Radius in pixels + * @color: Pixel color + ****************************************************************/ +void fillCircle(short x0, short y0, short r, short color) { + // startWrite(); + writeFastVLine(x0, y0 - r, 2 * r + 1, color); + fillCircleHelper(x0, y0, r, 3, 0, color); + // endWrite(); +} + +/**************************************************************** + * Function Name : drawTriangle + * Description : Draw a triangle + * Returns : NONE + * Params : @x0: Corner-1 X Co-ordinate + * @y0: Corner-1 Y Co-ordinate + * @x1: Corner-2 X Co-ordinate + * @y1: Corner-2 Y Co-ordinate + * @x2: Corner-3 X Co-ordinate + * @y2: Corner-3 Y Co-ordinate + * @color: Pixel color + ****************************************************************/ +void drawTriangle(short x0, short y0, short x1, short y1, short x2, short y2, + short color) { + drawLine(x0, y0, x1, y1, color); + drawLine(x1, y1, x2, y2, color); + drawLine(x2, y2, x0, y0, color); +} + +/**************************************************************** + * Function Name : fillTriangle + * Description : Fill a triangle + * Returns : NONE + * Params : @x0: Corner-1 X Co-ordinate + * @y0: Corner-1 Y Co-ordinate + * @x1: Corner-2 X Co-ordinate + * @y1: Corner-2 Y Co-ordinate + * @x2: Corner-3 X Co-ordinate + * @y2: Corner-3 Y Co-ordinate + * @color: Pixel color + ****************************************************************/ +void fillTriangle(short x0, short y0, short x1, short y1, short x2, short y2, + short color) { + short a, b, y, last, dx01, dy01, dx02, dy02, dx12, dy12; + int sa, sb; + + // Sort coordinates by Y order (y2 >= y1 >= y0) + if (y0 > y1) { + SWAP(y0, y1); + SWAP(x0, x1); + } + if (y1 > y2) { + SWAP(y2, y1); + SWAP(x2, x1); + } + if (y0 > y1) { + SWAP(y0, y1); + SWAP(x0, x1); + } + + // startWrite(); + if (y0 == + y2) { // Handle awkward all-on-same-line case as its own thing + a = b = x0; + if (x1 < a) + a = x1; + else if (x1 > b) + b = x1; + if (x2 < a) + a = x2; + else if (x2 > b) + b = x2; + writeFastHLine(a, y0, b - a + 1, color); + // endWrite(); + return; + } + + dx01 = x1 - x0; + dy01 = y1 - y0; + dx02 = x2 - x0; + dy02 = y2 - y0; + dx12 = x2 - x1; + dy12 = y2 - y1; + sa = 0; + sb = 0; + + // For upper part of triangle, find scanline crossings for segments + // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 + // is included here (and second loop will be skipped, avoiding a /0 + // error there), otherwise scanline y1 is skipped here and handled + // in the second loop...which also avoids a /0 error here if y0=y1 + // (flat-topped triangle). + if (y1 == y2) + last = y1; // Include y1 scanline + else + last = y1 - 1; // Skip it + + for (y = y0; y <= last; y++) { + a = x0 + sa / dy01; + b = x0 + sb / dy02; + sa += dx01; + sb += dx02; + /* longhand: + a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); + b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + */ + if (a > b) SWAP(a, b); + writeFastHLine(a, y, b - a + 1, color); + } + + // For lower part of triangle, find scanline crossings for segments + // 0-2 and 1-2. This loop is skipped if y1=y2. + sa = dx12 * (y - y1); + sb = dx02 * (y - y0); + for (; y <= y2; y++) { + a = x1 + sa / dy12; + b = x0 + sb / dy02; + sa += dx12; + sb += dx02; + /* longhand: + a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); + b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + */ + if (a > b) SWAP(a, b); + writeFastHLine(a, y, b - a + 1, color); + } + // endWrite(); +} + +/**************************************************************** + * Function Name : drawRoundRect + * Description : Draw a rounded rectangle + * Returns : NONE + * Params : @x: X Co-ordinate + * @y: Y Co-ordinate + * @w: Width + * @h: height + * @r: Corner radius + * @color: Pixel color + ****************************************************************/ +void drawRoundRect(short x, short y, short w, short h, short r, short color) { + // smarter version + // startWrite(); + writeFastHLine(x + r, y, w - 2 * r, color); // Top + writeFastHLine(x + r, y + h - 1, w - 2 * r, color); // Bottom + writeFastVLine(x, y + r, h - 2 * r, color); // Left + writeFastVLine(x + w - 1, y + r, h - 2 * r, color); // Right + // draw four corners + drawCircleHelper(x + r, y + r, r, 1, color); + drawCircleHelper(x + w - r - 1, y + r, r, 2, color); + drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, color); + drawCircleHelper(x + r, y + h - r - 1, r, 8, color); + // endWrite(); +} + +/**************************************************************** + * Function Name : fillRoundRect + * Description : Fill a rounded rectangle + * Returns : NONE + * Params : @x: X Co-ordinate + * @y: Y Co-ordinate + * @w: Width + * @h: height + * @r: Corner radius + * @color: Pixel color + ****************************************************************/ +void fillRoundRect(short x, short y, short w, short h, short r, short color) { + // smarter version + // startWrite(); + fillRect(x + r, y, w - 2 * r, h, color); + + // draw four corners + fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color); + fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1, color); + // endWrite(); +} + +/*---------------------------------------------------------------------------- + * BITMAP API's + ----------------------------------------------------------------------------*/ + +/**************************************************************** + * Function Name : drawBitmap + * Description : Draw a bitmap + * Returns : NONE + * Params : @x: X Co-ordinate + * @y: Y Co-ordinate + * @bitmap: bitmap to display + * @w: Width + * @h: height + * @color: Pixel color + ****************************************************************/ +void drawBitmap(short x, short y, const unsigned char bitmap[], short w, + short h, short color) { + short byteWidth = 0, j = 0, i = 0; + unsigned char byte = 0; + byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte + + for (j = 0; j < h; j++, y++) { + for (i = 0; i < w; i++) { + if (i & 7) + byte <<= 1; + else + byte = pgm_read_byte( + &bitmap[j * byteWidth + i / 8]); + if (byte & 0x80) drawPixel(x + i, y, color); + } + } +} + +/*---------------------------------------------------------------------------- + * TEXT AND CHARACTER HANDLING API's + ----------------------------------------------------------------------------*/ + +/**************************************************************** + * Function Name : setCursor + * Description : Sets the cursor on f(x,y) + * Returns : NONE. + * Params : @x - X-Cordinate + * @y - Y-Cordinate + ****************************************************************/ +void setCursor(short x, short y) { + cursor_x = x; + cursor_y = y; +} + +/**************************************************************** + * Function Name : getCursorX + * Description : Get cursor at X- Cordinate + * Returns : x cordinate value. + ****************************************************************/ +short getCursorX() { return cursor_x; } + +/**************************************************************** + * Function Name : getCursorY + * Description : Get cursor at Y- Cordinate + * Returns : y cordinate value. + ****************************************************************/ +short getCursorY() { return cursor_y; } + +/**************************************************************** + * Function Name : setTextSize + * Description : Set text size + * Returns : @s - font size + ****************************************************************/ +void setTextSize(unsigned char s) { textsize = (s > 0) ? s : 1; } + +/**************************************************************** + * Function Name : setTextColor + * Description : Set text color + * Returns : @c - Color + ****************************************************************/ +void setTextColor(short c) { + // For 'transparent' background, we'll set the bg + // to the same as fg instead of using a flag + textcolor = textbgcolor = c; +} + +/**************************************************************** + * Function Name : setTextWrap + * Description : Wraps the text + * Returns : @w - enable or disbale wrap + ****************************************************************/ +void setTextWrap(bool w) { wrap = w; } + +/**************************************************************** + * Function Name : getRotation + * Description : Get the rotation value + * Returns : NONE. + ****************************************************************/ +unsigned char getRotation() { return _rotation; } + +/**************************************************************** + * Function Name : drawBitmap + * Description : Draw a character + * Returns : NONE + * Params : @x: X Co-ordinate + * @y: Y Co-ordinate + * @c: Character + * @size: Scaling factor + * @bg: Background color + * @color: Pixel color + ****************************************************************/ +void drawChar(short x, short y, unsigned char c, short color, short bg, + unsigned char size) { + unsigned char line = 0, *bitmap = NULL, w = 0, h = 0, xx = 0, yy = 0, + bits = 0, bit = 0; + char i = 0, j = 0, xo = 0, yo = 0; + short bo = 0, xo16 = 0, yo16 = 0; + GFXglyphPtr glyph; + if (!gfxFont) { + // 'Classic' built-in font + if ((x >= _width) || (y >= _height) || + ((x + 6 * size - 1) < 0) || ((y + 8 * size - 1) < 0)) + return; + + // Handle 'classic' charset behavior + if (!_cp437 && (c >= 176)) c++; + + // Char bitmap = 5 columns + for (i = 0; i < 5; i++) { + line = pgm_read_byte(&ssd1306_font5x7[c * 5 + i]); + for (j = 0; j < 8; j++, line >>= 1) { + if (line & 1) { + if (size == 1) + drawPixel(x + i, y + j, color); + else + fillRect(x + i * size, + y + j * size, size, + size, color); + } else if (bg != color) { + if (size == 1) + drawPixel(x + i, y + j, bg); + else + fillRect(x + i * size, + y + j * size, size, + size, bg); + } + } + } + + // If opaque, draw vertical line for last column + if (bg != color) { + if (size == 1) + writeFastVLine(x + 5, y, 8, bg); + else + fillRect(x + 5 * size, y, size, 8 * size, bg); + } + + } + // Custom font + else { + // Character is assumed previously filtered by write() to + // eliminate newlines, returns, non-printable characters, etc. + // Calling drawChar() directly with 'bad' characters of font may + // cause mayhem! + + c -= (unsigned char)pgm_read_byte(&gfxFont->first); + glyph = &(((GFXglyphT *)pgm_read_pointer(&gfxFont->glyph))[c]); + bitmap = (unsigned char *)pgm_read_pointer(&gfxFont->bitmap); + bo = pgm_read_word(&glyph->bitmapOffset); + w = pgm_read_byte(&glyph->width); + h = pgm_read_byte(&glyph->height); + xo = pgm_read_byte(&glyph->xOffset); + yo = pgm_read_byte(&glyph->yOffset); + + if (size > 1) { + xo16 = xo; + yo16 = yo; + } + + // Todo: Add character clipping here + + // NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS. + // THIS IS ON PURPOSE AND BY DESIGN. The background color + // feature has typically been used with the 'classic' font to + // overwrite old screen contents with new data. This ONLY works + // because the characters are a uniform size; it's not a + // sensible thing to do with proportionally-spaced fonts with + // glyphs of varying sizes (and that may overlap). To replace + // previously-drawn text when using a custom font, use the + // getTextBounds() function to determine the smallest rectangle + // encompassing a string, erase the area with fillRect(), then + // draw new text. This WILL unfortunately 'blink' the text, but + // is unavoidable. Drawing 'background' pixels will NOT fix + // this, only creates a new set of problems. Have an idea to + // work around this (a canvas object type for MCUs that can + // afford the RAM and displays supporting setAddrWindow() and + // pushColors()), but haven't implemented this yet. + for (yy = 0; yy < h; yy++) { + for (xx = 0; xx < w; xx++) { + if (!(bit++ & 7)) { + bits = pgm_read_byte(&bitmap[bo++]); + } + if (bits & 0x80) { + if (size == 1) { + drawPixel(x + xo + xx, + y + yo + yy, color); + } else { + fillRect(x + (xo16 + xx) * size, + y + (yo16 + yy) * size, + size, size, color); + } + } + bits <<= 1; + } + } + } // End classic vs custom font +} + +/**************************************************************** + * Function Name : write + * Description : Base function for text and character handling + * Returns : 1 + * Params : @c: Character + ****************************************************************/ +short oled_write(unsigned char c) { + unsigned char first = 0, w = 0, h = 0; + short xo = 0; + GFXglyphPtr glyph; + if (!gfxFont) { + // 'Classic' built-in font + if (c == '\n') { + // Newline? + cursor_x = 0; // Reset x to zero, + cursor_y += textsize * 8; // advance y one line + } else if (c != '\r') { + // Ignore carriage returns + if (wrap && ((cursor_x + textsize * 6) > _width)) { + // Off right? + cursor_x = 0; // Reset x to zero, + cursor_y += textsize * 8; // advance y one line + } + drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, + textsize); + cursor_x += textsize * 6; // Advance x one char + } + + } else { + // Custom font + if (c == '\n') { + cursor_x = 0; + cursor_y += + (short)textsize * + (unsigned char)pgm_read_byte(&gfxFont->yAdvance); + } else if (c != '\r') { + first = pgm_read_byte(&gfxFont->first); + if ((c >= first) && (c <= (unsigned char)pgm_read_byte( + &gfxFont->last))) { + glyph = &(((GFXglyphT *)pgm_read_pointer( + &gfxFont->glyph))[c - first]); + w = pgm_read_byte(&glyph->width); + h = pgm_read_byte(&glyph->height); + if ((w > 0) && (h > 0)) { + // Is there an associated bitmap? + xo = (char)pgm_read_byte( + &glyph->xOffset); // sic + if (wrap && + ((cursor_x + textsize * (xo + w)) > + _width)) { + cursor_x = 0; + cursor_y += + (short)textsize * + (unsigned char) + pgm_read_byte( + &gfxFont->yAdvance); + } + drawChar(cursor_x, cursor_y, c, + textcolor, textbgcolor, + textsize); + } + cursor_x += (unsigned char)pgm_read_byte( + &glyph->xAdvance) * + (short)textsize; + } + } + } + return 1; +} + +/**************************************************************** + * Function Name : print + * Description : Base function for printing strings + * Returns : No. of characters printed + * Params : @buffer: Ptr to buffer containing the string + * @size: Length of the string. + ****************************************************************/ +short print(const unsigned char *buffer, short size) { + short n = 0; + while (size--) { + if (oled_write(*buffer++)) + n++; + else + break; + } + return (n); +} + +/**************************************************************** + * Function Name : print_str + * Description : Print strings + * Returns : No. of characters printed + * Params : @strPtr: Ptr to buffer containing the string + ****************************************************************/ +short print_str(const unsigned char *strPtr) { + return print(strPtr, strlen(strPtr)); +} + +/**************************************************************** + * Function Name : println + * Description : Move to next line + * Returns : No. of characters printed + * Params : NONE. + ****************************************************************/ +short println() { return print_str("\r\n"); } + +/**************************************************************** + * Function Name : print_strln + * Description : Print strings and move to next line + * Returns : No. of characters printed + * Params : @strPtr: Ptr to buffer containing the string + ****************************************************************/ +short print_strln(const unsigned char *strPtr) { + short n = 0; + n = print(strPtr, strlen(strPtr)); + n += print_str("\r\n"); + return (n); +} + +/*---------------------------------------------------------------------------- + * NUMBERS HANDLING API's + ----------------------------------------------------------------------------*/ + +/**************************************************************** + * Function Name : printNumber + * Description : Base function to print unsigned numbers + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber(unsigned long n, unsigned char base) { + unsigned long m = 0; + char c = 0; + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + do { + m = n; + n /= base; + c = m - base * n; + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while (n); + // return oled_write((unsigned char)str); + return print_str(str); +} + +/**************************************************************** + * Function Name : printNumber_UL + * Description : Print unsigned long data types + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_UL(unsigned long n, int base) { + if (base == 0) + return oled_write(n); + else + return printNumber(n, base); +} + +/**************************************************************** + * Function Name : printNumber_UL_ln + * Description : Print unsigned long & advance to next line + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_UL_ln(unsigned long num, int base) { + short n = 0; + n = printNumber(num, base); + n += println(); + return (n); +} + +/**************************************************************** + * Function Name : printNumber_UI + * Description : Print unsigned int data types + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_UI(unsigned int n, int base) { + return printNumber((unsigned long)n, base); +} + +/**************************************************************** + * Function Name : printNumber_UI_ln + * Description : Print unsigned int & advance to next line + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_UI_ln(unsigned int n, int base) { + short a = 0; + a = printNumber((unsigned long)n, base); + a += println(); + return (a); +} + +/**************************************************************** + * Function Name : printNumber_UC + * Description : Print unsigned char data types + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_UC(unsigned char b, int base) { + return printNumber((unsigned long)b, base); +} + +/**************************************************************** + * Function Name : printNumber_UC_ln + * Description : Print unsigned char & advance to next line + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_UC_ln(unsigned char b, int base) { + short n = 0; + n = printNumber((unsigned long)b, base); + n += println(); + return (n); +} + +/**************************************************************** + * Function Name : printNumber_L + * Description : Print Long data types + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_L(long n, int base) { + int t = 0; + if (base == 0) { + return oled_write(n); + } else if (base == 10) { + if (n < 0) { + t = oled_write('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +/**************************************************************** + * Function Name : printNumber_UC_ln + * Description : Print long & advance to next line + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_L_ln(long num, int base) { + short n = 0; + n = printNumber_L(num, base); + n += println(); + return n; +} + +/**************************************************************** + * Function Name : printNumber_I + * Description : Print int data types + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_I(int n, int base) { return printNumber_L((long)n, base); } + +/**************************************************************** + * Function Name : printNumber_I_ln + * Description : Print int & advance to next line + * Returns : No. of characters printed + * Params : @n: Number + * @base: Base e.g. HEX, BIN... + ****************************************************************/ +short printNumber_I_ln(int n, int base) { + short a = 0; + a = printNumber_L((long)n, base); + a += println(); + return a; +} + +/**************************************************************** + * Function Name : printFloat + * Description : Print floating Pt. No's. + * Returns : No. of characters printed + * Params : @n: Number + * @digits: Resolution + ****************************************************************/ +short printFloat(double number, unsigned char digits) { + unsigned char i = 0; + short n = 0; + unsigned long int_part = 0; + double remainder = 0.0; + int toPrint = 0; + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + + if (isnan(number)) return print_str("nan"); + if (isinf(number)) return print_str("inf"); + if (number > 4294967040.0) + return print_str("ovf"); // constant determined empirically + if (number < -4294967040.0) + return print_str("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) { + n += oled_write('-'); + number = -number; + } + + for (i = 0; i < digits; ++i) rounding /= 10.0; + + number += rounding; + + // Extract the integer part of the number and print it + int_part = (unsigned long)number; + remainder = number - (double)int_part; + n += printNumber_UL(int_part, DEC); + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) { + n += print_str("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) { + remainder *= 10.0; + toPrint = (int)remainder; + n += printNumber_I(toPrint, DEC); + remainder -= toPrint; + } + return n; +} + +/**************************************************************** + * Function Name : printFloat_ln + * Description : Print floating Pt. No and advance to next line + * Returns : No. of characters printed + * Params : @n: Number + * @digits: Resolution + ****************************************************************/ +short printFloat_ln(double num, int digits) { + short n = 0; + n = printFloat(num, digits); + n += println(); + return n; +} diff --git a/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h b/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h new file mode 100644 index 000000000..9a512589f --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h @@ -0,0 +1,216 @@ +/* + * MIT License + +Copyright (c) 2017 DeeplyEmbedded + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * SSD1306_OLED.h + * + * Created on : Sep 21, 2017 + * Author : Vinay Divakar + * Website : www.deeplyembedded.org + */ + +#ifndef SSD1306_OLED_H_ +#define SSD1306_OLED_H_ + +/* Lib's */ +#include + +/* Find Min and Max - MACROS */ +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +/* I2C Address of SSD1306 */ +#define SSD1306_OLED_ADDR 0x3C +#define DISPLAY_BUFF_SIZE (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8) + +/* COLOR MACROS */ +#define WHITE 1 +#define BLACK 0 +#define INVERSE 2 + +/* Number output format */ +#define DEC 10 +#define HEX 16 +#define OCT 8 +#define BIN 2 +#define DEFAULT 0 + +/*D/C# bit is '0' indicating that following + * byte is a command. '1' is for data + */ +#define SSD1306_CNTRL_CMD 0x00 +#define SSD1306_CNTRL_DATA 0x40 + +/*-----------------------Enable the WxL of the Display + * ---------------------------*/ +//#define SSD1306_128_64 +#define SSD1306_128_32 +//#define SSD1306_96_16 +/*--------------------------------------------------------------------------------*/ + +/* LCD HxW i.e. 64x128 || WxL i.e. 128x64 */ +#if defined SSD1306_128_64 +#define SSD1306_LCDWIDTH 128 +#define SSD1306_LCDHEIGHT 64 +#endif +#if defined SSD1306_128_32 +#define SSD1306_LCDWIDTH 128 +#define SSD1306_LCDHEIGHT 32 +#endif +#if defined SSD1306_96_16 +#define SSD1306_LCDWIDTH 96 +#define SSD1306_LCDHEIGHT 16 +#endif + +/* SSD1306 Commands */ +#define SSD1306_DISPLAY_OFF 0xAE +#define SSD1306_SET_DISP_CLK 0xD5 +#define SSD1306_SET_MULTIPLEX 0xA8 +#define SSD1306_SET_DISP_OFFSET 0xD3 +#define SSD1306_SET_DISP_START_LINE 0x40 +#define SSD1306_CONFIG_CHARGE_PUMP 0x8D +#define SSD1306_SET_MEM_ADDR_MODE 0x20 +#define SSD1306_SEG_REMAP (0xA0 | 0x01) +#define SSD1306_SEG_REMAP1 0xA0 +#define SSD1306_SET_COMSCANDEC 0xC8 +#define SSD1306_SET_COMSCANDEC1 0xC0 +#define SSD1306_SET_COMPINS 0xDA +#define SSD1306_SET_CONTRAST 0x81 +#define SSD1306_SET_PRECHARGE 0xD9 +#define SSD1306_SET_VCOMDETECT 0xDB +#define SSD1306_DISPLAYALLON_RESUME 0xA4 +#define SSD1306_NORMAL_DISPLAY 0xA6 +#define SSD1306_DISPLAYON 0xAF +#define SSD1306_SET_COL_ADDR 0x21 +#define SSD1306_PAGEADDR 0x22 +#define SSD1306_INVERT_DISPLAY 0x01 +#define SSD1306_NORMALIZE_DISPLAY 0x00 + +/* SDD1306 Scroll Commands */ +#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 +#define SSD1306_ACTIVATE_SCROLL 0x2F +#define SSD1306_DEACTIVATE_SCROLL 0x2E +#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26 +#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27 +#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 +#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A +#define SSD1306_INVERTDISPLAY 0xA7 + +/* SSD1306 Configuration Commands */ +#define SSD1306_DISPCLK_DIV 0x80 +#if defined SSD1306_128_64 +#define SSD1306_MULT_64 0x3F +#endif +#if defined SSD1306_128_32 +#define SSD1306_MULT_64 0x1F +#endif +#define SSD1306_MULT_64 0x1F +#define SSD1306_DISP_OFFSET_VAL 0x00 +#define SSD1306_COL_START_ADDR 0x00 // Reset to = 0 +#define SSD1306_COL_END_ADDR (SSD1306_LCDWIDTH - 1) // Reset to = 127 +#define SSD1306_PG_START_ADDR 0x00 +#define SSD1306_PG_END_ADDR 7 +#define SSD1306_CHARGE_PUMP_EN 0x14 +#if defined SSD1306_128_64 +#define SSD1306_CONFIG_COM_PINS 0x12 +#endif +#if defined SSD1306_128_32 +#define SSD1306_CONFIG_COM_PINS 0x02 +#endif +#define SSD1306_CONTRAST_VAL 0xCF // 207 +#define SSD1306_PRECHARGE_VAL 0xF1 +#define SSD1306_VCOMH_VAL 0x40 +#define SSD1306_MULT_DAT (SSD1306_LCDHEIGHT - 1) +#define SSD1306_HOR_MM 0x00 + +/*SSD1306 Display API's */ +extern void clearDisplay(); +extern void display_Init_seq(); +extern void Display(); +extern void Init_Col_PG_addrs(unsigned char col_start_addr, + unsigned char col_end_addr, + unsigned char pg_start_addr, + unsigned char pg_end_addr); +extern void setRotation(unsigned char x); +extern void startscrollright(unsigned char start, unsigned char stop); +extern void startscrollleft(unsigned char start, unsigned char stop); +extern void startscrolldiagright(unsigned char start, unsigned char stop); +extern void startscrolldiagleft(unsigned char start, unsigned char stop); +extern void stopscroll(); +extern void setCursor(short x, short y); +extern short getCursorX(); +extern short getCursorY(); +extern unsigned char getRotation(); +extern void invertDisplay(unsigned char i); +extern void display_rotate(); +extern void display_normal(); + +/*SSD1306 Graphics Handling API's */ +extern signed char drawPixel(short x, short y, short color); +extern void writeLine(short x0, short y0, short x1, short y1, short color); +extern void drawCircleHelper(short x0, short y0, short r, + unsigned char cornername, short color); +extern void drawLine(short x0, short y0, short x1, short y1, short color); +extern void drawRect(short x, short y, short w, short h, short color); +extern void fillRect(short x, short y, short w, short h, short color); +extern void drawCircle(short x0, short y0, short r, short color); +extern void fillCircleHelper(short x0, short y0, short r, + unsigned char cornername, short delta, + short color); +extern void fillCircle(short x0, short y0, short r, short color); +extern void drawTriangle(short x0, short y0, short x1, short y1, short x2, + short y2, short color); +extern void fillTriangle(short x0, short y0, short x1, short y1, short x2, + short y2, short color); +extern void drawRoundRect(short x, short y, short w, short h, short r, + short color); +extern void fillRoundRect(short x, short y, short w, short h, short r, + short color); +extern void drawBitmap(short x, short y, const unsigned char bitmap[], short w, + short h, short color); +extern short oled_write(unsigned char c); + +/*SSD1306 Text and Character Handling API's */ +extern void setTextSize(unsigned char s); +extern void setTextColor(short c); +extern void setTextWrap(bool w); +extern void drawChar(short x, short y, unsigned char c, short color, short bg, + unsigned char size); +extern short print_str(const unsigned char *strPtr); +extern short println(); +extern short print_strln(const unsigned char *strPtr); + +/*SSD1306 Number Handling API's */ +extern short printNumber(unsigned long n, unsigned char base); +extern short printNumber_UL(unsigned long n, int base); +extern short printNumber_UL_ln(unsigned long num, int base); +extern short printNumber_UI(unsigned int n, int base); +extern short printNumber_UI_ln(unsigned int n, int base); +extern short printNumber_UC(unsigned char b, int base); +extern short printNumber_UC_ln(unsigned char b, int base); +extern short printNumber_L(long n, int base); +extern short printNumber_L_ln(long num, int base); +extern short printNumber_I(int n, int base); +extern short printNumber_I_ln(int n, int base); +extern short printFloat(double number, unsigned char digits); +extern short printFloat_ln(double num, int digits); +#endif /* SSD1306_OLED_H_ */ diff --git a/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h b/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h new file mode 100644 index 000000000..8180a7393 --- /dev/null +++ b/luci-app-oled/luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h @@ -0,0 +1,18 @@ +#ifndef _GFXFONT_H_ +#define _GFXFONT_H_ + +typedef struct { // Data stored PER GLYPH + unsigned short bitmapOffset; // Pointer into GFXfont->bitmap + unsigned char width, height; // Bitmap dimensions in pixels + unsigned char xAdvance; // Distance to advance cursor (x axis) + char xOffset, yOffset; // Dist from cursor pos to UL corner +} GFXglyphT, *GFXglyphPtr; + +typedef struct { // Data stored for FONT AS A WHOLE: + unsigned char *bitmap; // Glyph bitmaps, concatenated + GFXglyphPtr glyph; // Glyph array + unsigned char first, last; // ASCII extents + unsigned char yAdvance; // Newline distance (y axis) +} GFXfontT, *GFXfontPtr; + +#endif // _GFXFONT_H_ diff --git a/luci-app-oled/root/etc/init.d/oled b/luci-app-oled/root/etc/init.d/oled deleted file mode 100755 index a11f611df..000000000 --- a/luci-app-oled/root/etc/init.d/oled +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/sh /etc/rc.common -START=1OO - -PROG=/usr/bin/oled - -stop() { - kill -2 $(pgrep /usr/bin/oled) - kill -9 $(pgrep -f /usr/sbin/netspeed) - echo "oled exit..." -} - -start() { - enabled=$(uci get oled.@oled[0].enable) - if [ $enabled -eq 0 ]; then - exit 0 - fi - - autoswitch=$(uci get oled.@oled[0].autoswitch) - from=$(uci get oled.@oled[0].from) - to=$(uci get oled.@oled[0].to) - - if [ ${autoswitch} -eq 1 ]; then - hour=$(date +"%H") - min=$(date +"%M") - ihour=`expr $hour + 0` - imin=`expr $min + 0` - now=$(($ihour*60+$imin)) - if [[ $now -lt $from || $now -gt $to ]]; then - stop - exit 0 - fi - fi - - #crontab daemon - if ! grep "/etc/init.d/oled \+restart" /etc/crontabs/root >/dev/null 2>&1; then - echo "*/5 * * * * /etc/init.d/oled restart >/dev/null 2>&1" >> /etc/crontabs/root - fi - - date=$(uci get oled.@oled[0].date) - lanip=$(uci get oled.@oled[0].lanip) - cputemp=$(uci get oled.@oled[0].cputemp) - cpufreq=$(uci get oled.@oled[0].cpufreq) - netspeed=$(uci get oled.@oled[0].netspeed) - time=$(uci get oled.@oled[0].time) - drawline=$(uci get oled.@oled[0].drawline) - drawrect=$(uci get oled.@oled[0].drawrect) - fillrect=$(uci get oled.@oled[0].fillrect) - drawcircle=$(uci get oled.@oled[0].drawcircle) - drawroundrect=$(uci get oled.@oled[0].drawroundrect) - fillroundrect=$(uci get oled.@oled[0].fillroundrect) - drawtriangle=$(uci get oled.@oled[0].drawtriangle) - filltriangle=$(uci get oled.@oled[0].filltriangle) - displaybitmap=$(uci get oled.@oled[0].displaybitmap) - displayinvertnormal=$(uci get oled.@oled[0].displayinvertnormal) - drawbitmapeg=$(uci get oled.@oled[0].drawbitmapeg) - scroll=$(uci get oled.@oled[0].scroll) - text=$(uci get oled.@oled[0].text) - netsource=$(uci get oled.@oled[0].netsource) - - - if [ ${netspeed} -eq 1 ]; then - nohup /usr/sbin/netspeed ${netsource} >/dev/null 2>&1 & - else - kill -9 $(pgrep -f /usr/sbin/netspeed) - rm -f /tmp/netspeed - fi - nohup ${PROG} ${date} ${lanip} ${cputemp} ${cpufreq} ${netspeed} ${time} ${drawline} ${drawrect} ${fillrect} ${drawcircle} ${drawroundrect} ${fillroundrect} ${drawtriangle} ${filltriangle} ${displaybitmap} ${displayinvertnormal} ${drawbitmapeg} ${scroll} "${text}" "${netsource}" 1 > /dev/null 2>&1 & -} - - - - -restart(){ - enabled=$(uci get oled.@oled[0].enable) - pgrep -f ${PROG} >/dev/null - if [ $? -eq 0 ]; then - if [ $enabled -eq 1 ]; then - autoswitch=$(uci get oled.@oled[0].autoswitch) - from=$(uci get oled.@oled[0].from) - to=$(uci get oled.@oled[0].to) - if [ ${autoswitch} -eq 1 ]; then - hour=$(date +"%H") - min=$(date +"%M") - ihour=`expr $hour + 0` - imin=`expr $min + 0` - now=$(($ihour*60+$imin)) - if [[ $now -lt $from || $now -gt $to ]]; then - stop - exit 0 - fi - fi - - date=$(uci get oled.@oled[0].date) - lanip=$(uci get oled.@oled[0].lanip) - cputemp=$(uci get oled.@oled[0].cputemp) - cpufreq=$(uci get oled.@oled[0].cpufreq) - netspeed=$(uci get oled.@oled[0].netspeed) - time=$(uci get oled.@oled[0].time) - drawline=$(uci get oled.@oled[0].drawline) - drawrect=$(uci get oled.@oled[0].drawrect) - fillrect=$(uci get oled.@oled[0].fillrect) - drawcircle=$(uci get oled.@oled[0].drawcircle) - drawroundrect=$(uci get oled.@oled[0].drawroundrect) - fillroundrect=$(uci get oled.@oled[0].fillroundrect) - drawtriangle=$(uci get oled.@oled[0].drawtriangle) - filltriangle=$(uci get oled.@oled[0].filltriangle) - displaybitmap=$(uci get oled.@oled[0].displaybitmap) - displayinvertnormal=$(uci get oled.@oled[0].displayinvertnormal) - drawbitmapeg=$(uci get oled.@oled[0].drawbitmapeg) - scroll=$(uci get oled.@oled[0].scroll) - text=$(uci get oled.@oled[0].text) - netsource=$(uci get oled.@oled[0].netsource) - - - kill -9 $(pgrep /usr/bin/oled) - kill -9 $(pgrep -f /usr/sbin/netspeed) - - if [ ${netspeed} -eq 1 ]; then - nohup /usr/sbin/netspeed ${netsource} >/dev/null 2>&1 & - else - kill -9 $(pgrep -f /usr/sbin/netspeed) - rm -f /tmp/netspeed - fi - nohup ${PROG} ${date} ${lanip} ${cputemp} ${cpufreq} ${netspeed} ${time} ${drawline} ${drawrect} ${fillrect} ${drawcircle} ${drawroundrect} ${fillroundrect} ${drawtriangle} ${filltriangle} ${displaybitmap} ${displayinvertnormal} ${drawbitmapeg} ${scroll} "${text}" "${netsource}" 0 > /dev/null 2>&1 & - else - stop - fi - - else - if [ $enabled -eq 1 ]; then - start - else - exit 0 - fi - fi -} - -boot(){ - start -} diff --git a/luci-app-oled/root/etc/uci-defaults/oled b/luci-app-oled/root/etc/uci-defaults/oled deleted file mode 100644 index 81bc0a23f..000000000 --- a/luci-app-oled/root/etc/uci-defaults/oled +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@oled[-1] - add ucitrack oled - set ucitrack.@oled[-1].init=oled - commit ucitrack -EOF - -rm -rf /tmp/luci-* -exit 0 diff --git a/luci-app-oled/root/usr/sbin/netspeed b/luci-app-oled/root/usr/sbin/netspeed deleted file mode 100755 index 6be8ca48d..000000000 --- a/luci-app-oled/root/usr/sbin/netspeed +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/ash -IF=$1 -if [ -z "$IF" ]; then - IF=`ls -1 /sys/class/net/ | head -1` -fi -RXPREV=-1 -TXPREV=-1 -echo "Listening $IF..." -while [ 1 == 1 ] ; do - RX=`cat /sys/class/net/${IF}/statistics/rx_bytes` - TX=`cat /sys/class/net/${IF}/statistics/tx_bytes` - if [ $RXPREV -ne -1 ] ; then - let BWRX=$RX-$RXPREV - let BWTX=$TX-$TXPREV - echo "$BWRX $BWTX">/tmp/netspeed - fi - RXPREV=$RX - TXPREV=$TX - sleep 1 -done diff --git a/luci-app-oled/src/Example_Code/Main.c b/luci-app-oled/src/Example_Code/Main.c deleted file mode 100644 index 9bf87e697..000000000 --- a/luci-app-oled/src/Example_Code/Main.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Main.c - * - * Created on : Sep 6, 2017 - * Author : Vinay Divakar - * Description : Example usage of the SSD1306 Driver API's - * Website : www.deeplyembedded.org - */ - -/* Lib Includes */ -#include -#include -#include -#include -#include - -/* Header Files */ -#include "I2C.h" -#include "SSD1306_OLED.h" -#include "example_app.h" - -/* Oh Compiler-Please leave me as is */ -volatile unsigned char flag = 0; - -/* Alarm Signal Handler */ -void ALARMhandler(int sig) -{ - /* Set flag */ - flag = 5; -} - -void BreakDeal(int sig) -{ - clearDisplay(); - usleep(1000000); - Display(); - exit(0); -} - - -int main(int argc, char* argv[]) -{ - int date=atoi(argv[1]); - int lanip=atoi(argv[2]); - int cputemp=atoi(argv[3]); - int cpufreq=atoi(argv[4]); - int netspeed=atoi(argv[5]); - int time=atoi(argv[6]); - int drawline=atoi(argv[7]); - int drawrect=atoi(argv[8]); - int fillrect=atoi(argv[9]); - int drawcircle=atoi(argv[10]); - int drawroundcircle=atoi(argv[11]); - int fillroundcircle=atoi(argv[12]); - int drawtriangle=atoi(argv[13]); - int filltriangle=atoi(argv[14]); - int displaybitmap=atoi(argv[15]); - int displayinvertnormal=atoi(argv[16]); - int drawbitmapeg=atoi(argv[17]); - int scroll=atoi(argv[18]); - char *text=argv[19]; - char *eth = argv[20]; - int needinit=atoi(argv[21]); - - - /* Initialize I2C bus and connect to the I2C Device */ - if(init_i2c_dev(I2C_DEV0_PATH, SSD1306_OLED_ADDR) == 0) - { - printf("(Main)i2c-2: Bus Connected to SSD1306\r\n"); - } - else - { - printf("(Main)i2c-2: OOPS! Something Went Wrong\r\n"); - exit(1); - } - - /* Register the Alarm Handler */ - signal(SIGALRM, ALARMhandler); - signal(SIGINT, BreakDeal); - //signal(SIGTERM, BreakDeal); -/* Run SDD1306 Initialization Sequence */ - if (needinit==1) {display_Init_seq();} - - /* Clear display */ - clearDisplay(); - - // draw a single pixel -// drawPixel(0, 1, WHITE); -// Display(); -// usleep(1000000); -// clearDisplay(); - - // draw many lines - while(1){ - - if(scroll){ - testscrolltext(text); - usleep(1000000); - clearDisplay(); - } - - if(drawline){ - testdrawline(); - usleep(1000000); - clearDisplay(); - } - - - // draw rectangles - if(drawrect){ - testdrawrect(); - usleep(1000000); - clearDisplay(); - } - - // draw multiple rectangles - if(fillrect){ - testfillrect(); - usleep(1000000); - clearDisplay(); - } - - // draw mulitple circles - if(drawcircle){ - testdrawcircle(); - usleep(1000000); - clearDisplay(); - } - - - // draw a white circle, 10 pixel radius - if(drawroundcircle){ - testdrawroundrect(); - usleep(1000000); - clearDisplay(); - } - - - // Fill the round rectangle - if(fillroundcircle){ - testfillroundrect(); - usleep(1000000); - clearDisplay(); - } - - // Draw triangles - if(drawtriangle){ - testdrawtriangle(); - usleep(1000000); - clearDisplay(); - } - // Fill triangles - if(filltriangle){ - testfilltriangle(); - usleep(1000000); - clearDisplay(); - } - - // Display miniature bitmap - if(displaybitmap){ - display_bitmap(); - Display(); - usleep(1000000); - }; - // Display Inverted image and normalize it back - if(displayinvertnormal){ - display_invert_normal(); - clearDisplay(); - usleep(1000000); - Display(); - - } - - // Generate Signal after 20 Seconds - - // draw a bitmap icon and 'animate' movement - if(drawbitmapeg){ - alarm(10); - flag=0; - testdrawbitmap_eg(); - clearDisplay(); - usleep(1000000); - Display(); - } - - - //setCursor(0,0); - setTextColor(WHITE); - // info display - int sum = date+lanip+cpufreq+cputemp+netspeed; - if (sum == 0) {clearDisplay(); return 0;} - for(int i = 1; i < time; i++){ - if (sum == 1){//only one item for display - if (date) testdate(CENTER, 8); - if (lanip) testlanip(CENTER, 8); - if (cpufreq) testcpufreq(CENTER, 8); - if (cputemp) testcputemp(CENTER, 8); - if (netspeed) testnetspeed(SPLIT,0); - Display(); - usleep(1000000); - clearDisplay(); - }else if (sum == 2){//two items for display - if(date) {testdate(CENTER, 16*(date-1));} - if(lanip) {testlanip(CENTER, 16*(date+lanip-1));} - if(cpufreq) {testcpufreq(CENTER, 16*(date+lanip+cpufreq-1));} - if(cputemp) {testcputemp(CENTER, 16*(date+lanip+cpufreq+cputemp-1));} - if(netspeed) {testnetspeed(MERGE, 16*(date+lanip+cpufreq+cputemp+netspeed-1));} - Display(); - usleep(1000000); - clearDisplay(); - } - else{//more than two items for display - if(date) {testdate(FULL, 8*(date-1));} - if(lanip) {testlanip(FULL, 8*(date+lanip-1));} - if(cpufreq && cputemp) { - testcpu(8*(date+lanip)); - if(netspeed) {testnetspeed(FULL, 8*(date+lanip+1+netspeed-1));} - } - else{ - if(cpufreq) {testcpufreq(FULL, 8*(date+lanip+cpufreq-1));} - if(cputemp) {testcputemp(FULL, 8*(date+lanip+cpufreq+cputemp-1));} - if(netspeed) {testnetspeed(FULL, 8*(date+lanip+cpufreq+cputemp+netspeed-1));} - } - - Display(); - usleep(1000000); - clearDisplay(); - } - } - } - -} diff --git a/luci-app-oled/src/Example_Code/example_app.c b/luci-app-oled/src/Example_Code/example_app.c deleted file mode 100644 index 9ce62d025..000000000 --- a/luci-app-oled/src/Example_Code/example_app.c +++ /dev/null @@ -1,650 +0,0 @@ -/* - * MIT License - -Copyright (c) 2017 DeeplyEmbedded - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - * example_app.c - * - * Created on : Sep 6, 2017 - * Author : Vinay Divakar - * Website : www.deeplyembedded.org - */ - -/* Lib Includes */ -#include -#include -#include -#include -#include -#include -#include -#include "SSD1306_OLED.h" -#include "example_app.h" - -#define BUFMAX SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT - -/* MACRO's */ -#define LOGO16_GLCD_HEIGHT 16 -#define LOGO16_GLCD_WIDTH 16 -#define NUMFLAKES 10 -#define XPOS 0 -#define YPOS 1 -#define DELTAY 2 - - - -#define TIMESIZE 64 -//temperature -#define TEMPPATH "/sys/class/thermal/thermal_zone0/temp" -#define TEMPSIZE 5 -//cpu -#define FREQSIZE 8 -#define FREQPATH "cat /sys/devices/system/cpu/cpu[04]/cpufreq/cpuinfo_cur_freq" -//ip -#define IPPATH "ifconfig br-lan|grep 'inet addr:'|cut -d: -f2|awk '{print $1}'" -#define IPSIZE 20 -//netspeed -#define NETPATH "cat /tmp/netspeed" - -/* Extern volatile */ -extern volatile unsigned char flag; - -/* Bit Map - Taken from Adafruit SSD1306 OLED Library */ -static const unsigned char logo16_glcd_bmp[] = -{ - 0b00000000, 0b11000000, - 0b00000001, 0b11000000, - 0b00000001, 0b11000000, - 0b00000011, 0b11100000, - 0b11110011, 0b11100000, - 0b11111110, 0b11111000, - 0b01111110, 0b11111111, - 0b00110011, 0b10011111, - 0b00011111, 0b11111100, - 0b00001101, 0b01110000, - 0b00011011, 0b10100000, - 0b00111111, 0b11100000, - 0b00111111, 0b11110000, - 0b01111100, 0b11110000, - 0b01110000, 0b01110000, - 0b00000000, 0b00110000 -}; - -FILE *fp; -char content_buff[BUFMAX]; -char buf[BUFMAX]; -int display_offset =7; -/* draw many lines */ -void testdrawline() -{ - short i = 0; - for (i=0; i=0; i-=4) - { - drawLine(0, SSD1306_LCDHEIGHT-1, SSD1306_LCDWIDTH-1, i, WHITE); - Display(); - usleep(1000); - } - usleep(250000); - - clearDisplay(); - for (i=SSD1306_LCDWIDTH-1; i>=0; i-=4) - { - drawLine(SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, i, 0, WHITE); - Display(); - usleep(1000); - } - for (i=SSD1306_LCDHEIGHT-1; i>=0; i-=4) - { - drawLine(SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, 0, i, WHITE); - Display(); - usleep(1000); - } - usleep(250000); - - clearDisplay(); - for (i=0; i0; i-=5) - { - fillTriangle(SSD1306_LCDWIDTH/2, SSD1306_LCDHEIGHT/2-i, - SSD1306_LCDWIDTH/2-i, SSD1306_LCDHEIGHT/2+i, - SSD1306_LCDWIDTH/2+i, SSD1306_LCDHEIGHT/2+i, WHITE); - if (color == WHITE) - color = BLACK; - else - color = WHITE; - Display(); - usleep(1000); - } -} - -/* Display a bunch of characters and emoticons */ -void testdrawchar() -{ - unsigned char i = 0; - setTextSize(1); - setTextColor(WHITE); - setCursor(0,0); - - for (i=0; i < 168; i++) - { - if (i == '\n') - continue; - oled_write(i); - if ((i > 0) && (i % 21 == 0)) - println(); - } - Display(); - usleep(1000); -} - -/* Display "scroll" and scroll around */ -void testscrolltext(char* str) -{ - setTextSize(2); - setTextColor(WHITE); - setCursor(10,8); - sprintf(buf,"%s",str); - print_strln(buf); - Display(); - usleep(1000); - startscrollright(0x00, 0x0F); - usleep(5000000); - stopscroll(); - usleep(1000000); - startscrollleft(0x00, 0x0F); - usleep(5000000); - stopscroll(); - usleep(1000000); - startscrolldiagright(0x00, 0x07); - usleep(5000000); - startscrolldiagleft(0x00, 0x07); - usleep(5000000); - stopscroll(); -} - - - -/* Display Texts */ -void display_texts() -{ - setTextSize(1); - setTextColor(WHITE); - setCursor(10,0); - print_str("HELLO FELLAS!"); - println(); - printFloat_ln(3.141592, 4); //Print 4 No's after the decimal Pt. - printNumber_L_ln(-1234, DEC); - printNumber_UC_ln(170, BIN); - setTextSize(2); - setTextColor(WHITE); - print_str("0x"); - printNumber_UL_ln(0xDEADBEEF, HEX); -} - -/* Display miniature bitmap */ -void display_bitmap() -{ - drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1); -} - -/* Invert Display and Normalize it */ -void display_invert_normal() -{ - invertDisplay(SSD1306_INVERT_DISPLAY); - usleep(1000000); - invertDisplay(SSD1306_NORMALIZE_DISPLAY); - usleep(1000000); -} - -/* Draw a bitmap and 'animate' movement */ -void testdrawbitmap(const unsigned char *bitmap, unsigned char w, unsigned char h) -{ - unsigned char icons[NUMFLAKES][3], f = 0; - - // initialize - for (f=0; f< NUMFLAKES; f++) - { - icons[f][XPOS] = rand() % SSD1306_LCDWIDTH; - icons[f][YPOS] = 0; - icons[f][DELTAY] = (rand() % 5) + 1; - - /* Looks kinna ugly to me - Un-Comment if you need it */ - //print_str("x: "); - //printNumber_UC(icons[f][XPOS], DEC); - //print_str("y: "); - //printNumber_UC(icons[f][YPOS], DEC); - //print_str("dy: "); - //printNumber_UC(icons[f][DELTAY], DEC); - } - - while (flag != 5) - { - // draw each icon - for (f=0; f< NUMFLAKES; f++) - { - drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE); - } - Display(); - usleep(200000); - - // then erase it + move it - for (f=0; f< NUMFLAKES; f++) - { - drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK); - - // move it - icons[f][YPOS] += icons[f][DELTAY]; - - // if its gone, reinit - if (icons[f][YPOS] > SSD1306_LCDHEIGHT) - { - icons[f][XPOS] = rand() % SSD1306_LCDWIDTH; - icons[f][YPOS] = 0; - icons[f][DELTAY] = (rand() % 5) + 1; - } - } - } -} - -/* Draw bitmap and animate */ -void testdrawbitmap_eg() -{ - setTextSize(1); - setTextColor(WHITE); - setCursor(10,0); - testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH); -} - -/* Intro */ -void deeplyembedded_credits() -{ - setTextSize(1); - setTextColor(WHITE); - setCursor(1,0); - print_strln("deeplyembedded.org"); - println(); - print_strln("Author:Vinay Divakar"); - println(); - println(); - print_strln("THANK YOU"); -} - - -void testdate(int mode, int y) -{ - time_t rawtime; - time_t curtime; - uint8_t timebuff[TIMESIZE]; - curtime = time(NULL); - time(&rawtime); - switch (mode) - { - case CENTER: - setTextSize(2); - strftime(timebuff,80,"%H:%M",localtime(&rawtime)); - sprintf(buf,"%s",timebuff); - setCursor((127-strlen(buf)*11)/2-4, y); - break; - case FULL: - setTextSize(1); - strftime(timebuff,80,"%Y-%m-%d %H:%M:%S",localtime(&rawtime)); - sprintf(buf,"%s",timebuff); - setCursor(display_offset, y); - } - print_strln(buf); -} - - -void testlanip(int mode, int y) -{ - setTextSize(1); - if((fp=popen(IPPATH,"r"))!=NULL) - { - fscanf(fp,"%s",content_buff); - fclose(fp); - //ipbuff[strlen(ipbuff)-1]=32; - switch(mode) - { - case CENTER: - setTextSize(1); - sprintf(buf,"%s",content_buff); - setCursor((127-strlen(buf)*6)/2, y+4); - break; - - case FULL: - setTextSize(1); - sprintf(buf,"IP:%s",content_buff); - setCursor(display_offset, y); - } - print_strln(buf); - } - -} - - -void testcputemp(int mode, int y) -{ - if((fp=fopen(TEMPPATH,"r"))!=NULL) - { - fgets(content_buff,TEMPSIZE,fp); - fclose(fp); - switch (mode) - { - case CENTER: - setTextSize(2); - sprintf(buf, "%.2f",atoi(content_buff)/100.0); - setCursor((127-(strlen(buf)+2)*11)/2-4, y); - print_str(buf); - oled_write(0); - oled_write(67); - drawCircle(getCursorX()-16, getCursorY()+3, 2, WHITE); - break; - case FULL: - setTextSize(1); - sprintf(buf,"CPU TEMP:%.2f",atoi(content_buff)/100.0); - setCursor(display_offset, y); - print_str(buf); - oled_write(0); - oled_write(67); - drawCircle(getCursorX()-8, getCursorY()+1, 1, WHITE); - } - - } - -} - - -void testcpufreq(int mode, int y) -{ - if((fp=popen(FREQPATH,"r")) != NULL) - { - fgets(content_buff,FREQSIZE,fp); - fclose(fp); - switch(mode) - { - case CENTER: - setTextSize(2); - sprintf(buf,"%4dMHz",atoi(content_buff)/1000); - setCursor((127-strlen(buf)*11)/2-4, y); - break; - case FULL: - setTextSize(1); - sprintf(buf,"CPU FREQ:%4dMHz",atoi(content_buff)/1000); - setCursor(display_offset, y); - } - print_strln(buf); - } - -} - -void testnetspeed(int mode, int y) -{ - int rx,tx; - if((fp=popen(NETPATH,"r")) != NULL) - { - fscanf(fp,"%d %d", &rx, &tx); - fclose(fp); - rx = rx; - tx = tx; - switch(mode) - { - case SPLIT: - setTextSize(2); - if (tx < 1000) sprintf(buf, "%03dB", tx); - else if (tx > 1000000) sprintf(buf, "%03dM", tx/1000000); - else sprintf(buf, "%03dK", tx/1000); - setCursor((127-(strlen(buf)+1)*11)/2,0); - oled_write(24); - print_str(buf); - - if (rx < 1000) sprintf(buf, "%03dB", rx); - else if (rx > 1000000) sprintf(buf, "%03dM", rx/1000000); - else sprintf(buf, "%03dK", rx/1000); - setCursor((127-(strlen(buf)+1)*11)/2,16); - oled_write(25); - print_str(buf); - break; - case MERGE: - setTextSize(1); - if (tx < 1000) sprintf(buf, "%03dB ", tx); - else if (tx > 1000000) sprintf(buf, "%03dM", tx/1000000); - else sprintf(buf, "%03dK ", tx/1000); - setCursor((127-(2*strlen(buf)-1)*6)/2-4, y+4); - oled_write(24); - print_str(buf); - - if (rx < 1000) sprintf(buf, "%03dB", rx); - else if (rx > 1000000) sprintf(buf, "%03dM", rx/1000000); - else sprintf(buf, "%03dK", rx/1000); - oled_write(25); - print_str(buf); - break; - case FULL: - setTextSize(1); - setCursor(display_offset, y); - oled_write(24); - if (tx < 1000) sprintf(buf, "%03dB ", tx); - else if (tx > 1000000) sprintf(buf, "%03dM", tx/1000000); - else sprintf(buf, "%03dK ", tx/1000); - print_str(buf); - - oled_write(25); - if (rx < 1000) sprintf(buf, "%03dB", rx); - else if (rx > 1000000) sprintf(buf, "%03dM", rx/1000000); - else sprintf(buf, "%03dK", rx/1000); - print_str(buf); - } - } -} -void testcpu(int y) -{ -//freq - setTextSize(1); - setCursor(display_offset, y); - if((fp=popen(FREQPATH,"r")) != NULL) - { - fgets(content_buff,FREQSIZE,fp); - fclose(fp); - sprintf(buf,"CPU:%4dMHz ", atoi(content_buff)/1000); - print_str(buf); - } - - -//temp - if((fp=fopen(TEMPPATH,"r"))!=NULL) - { - fgets(content_buff,TEMPSIZE,fp); - fclose(fp); - sprintf(buf, "%.2f",atoi(content_buff)/100.0); - print_str(buf); - oled_write(0); - oled_write(67); - drawCircle(getCursorX()-8, getCursorY()+1, 1, WHITE); - } -} - -void testprintinfo() -{ - setTextSize(1); - setTextColor(WHITE); - setCursor(0,0); -//DATE - - time_t rawtime; - time_t curtime; - uint8_t timebuff[TIMESIZE]; - curtime = time(NULL); - time(&rawtime); - strftime(timebuff,80,"%Y-%m-%d_%w %H:%M:%S",localtime(&rawtime)); - sprintf(buf,"%s",timebuff); - print_strln(buf); - - //br-lan ip - if((fp=popen(IPPATH,"r"))!=NULL) - { - fscanf(fp,"%s",content_buff); - fclose(fp); - //ipbuff[strlen(ipbuff)-1]=32; - sprintf(buf,"IP:%s",content_buff); - print_strln(buf); - } - - //CPU temp - if((fp=popen(FREQPATH,"r")) != NULL) - { - fgets(content_buff,FREQSIZE,fp); - fclose(fp); - sprintf(buf,"CPU freq:%d MHz ",atoi(content_buff)/1000); - print_strln(buf); - } - - //cpu freq - if((fp=fopen(TEMPPATH,"r"))!=NULL) - { - fgets(content_buff,TEMPSIZE,fp); - fclose(fp); - sprintf(buf,"CPU temp:%.2f C",atoi(content_buff)/100.0); - print_strln(buf); - } - - - -} - diff --git a/luci-app-oled/src/Makefile b/luci-app-oled/src/Makefile deleted file mode 100644 index 0f1b25559..000000000 --- a/luci-app-oled/src/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -CC = gcc -LD = gcc - -SOURCES = SSD1306_OLED_Library/SSD1306_OLED.c Example_Code/Main.c Example_Code/example_app.c I2C_Library/I2C.c -OBJS := $(SOURCES:.c=.o) -CPPFLAGS := -I SSD1306_OLED_Library -I I2C_Library -CFLAGS := -g - -oled: $(OBJS) - $(CC) $^ -o $@ - -clean: - rm -rf oled $(OBJS) - -compile: oled - -install: compile - mkdir -p $(DESTDIR)/usr/bin - cp oled $(DESTDIR)/usr/bin/oled diff --git a/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c b/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c deleted file mode 100644 index 0cbd92bf2..000000000 --- a/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c +++ /dev/null @@ -1,2713 +0,0 @@ -/* - * MIT License - -Copyright (c) 2017 DeeplyEmbedded - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - * SSD1306_OLED.c - * - * Created on : Sep 26, 2017 - * Author : Vinay Divakar - * Description : SSD1306 OLED Driver, Graphics API's. - * Website : www.deeplyembedded.org - */ - -/* Lib Includes */ -#include -#include -#include -#include -#include -#include "I2C.h" -#include "SSD1306_OLED.h" -#include "gfxfont.h" - -/* Enable or Disable DEBUG Prints */ -//#define SSD1306_DBG - -/* MACROS */ -#define SWAP(x,y) {short temp; temp = x; x = y; y = temp;} -#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) -#define pgm_read_word(addr) (*(const unsigned long *)(addr)) -#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) -#define pgm_read_pointer(addr) ((void *)pgm_read_word(addr)) - -/* static Variables */ -static unsigned char _rotation = 0,textsize = 0; -static short _width = SSD1306_LCDWIDTH; -static short _height = SSD1306_LCDHEIGHT; -static short cursor_x = 0, cursor_y = 0, textcolor = 0, textbgcolor = 0; -static bool _cp437 = false, wrap = true; - -/* static struct objects */ -static GFXfontPtr gfxFont; - -/* Externs - I2C.c */ -extern I2C_DeviceT I2C_DEV_2; - -/* Chunk Buffer */ -static unsigned char chunk[17] = {0}; - -/* Memory buffer for displaying data on LCD - This is an Apple - Fruit */ -static unsigned char screen[DISPLAY_BUFF_SIZE] ={0}; - -/* Static Functions */ -static void transfer(); -static void drawFastVLine(short x, short y,short h, short color); -static void writeFastVLine(short x, short y, short h, short color); -static void drawFastHLine(short x, short y,short w, short color); -static void writeFastHLine(short x, short y, short w, short color); -static short print(const unsigned char *buffer, short size); - -// Standard ASCII 5x7 font -static const unsigned char ssd1306_font5x7[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, //space - 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, - 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, - 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, - 0x18, 0x3C, 0x7E, 0x3C, 0x18, - 0x1C, 0x57, 0x7D, 0x57, 0x1C, - 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, - 0x00, 0x18, 0x3C, 0x18, 0x00, - 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, - 0x00, 0x18, 0x24, 0x18, 0x00, - 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, - 0x30, 0x48, 0x3A, 0x06, 0x0E, - 0x26, 0x29, 0x79, 0x29, 0x26, - 0x40, 0x7F, 0x05, 0x05, 0x07, - 0x40, 0x7F, 0x05, 0x25, 0x3F, - 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, - 0x7F, 0x3E, 0x1C, 0x1C, 0x08, - 0x08, 0x1C, 0x1C, 0x3E, 0x7F, - 0x14, 0x22, 0x7F, 0x22, 0x14, - 0x5F, 0x5F, 0x00, 0x5F, 0x5F, - 0x06, 0x09, 0x7F, 0x01, 0x7F, - 0x00, 0x66, 0x89, 0x95, 0x6A, - 0x60, 0x60, 0x60, 0x60, 0x60, - 0x94, 0xA2, 0xFF, 0xA2, 0x94, - 0x08, 0x04, 0x7E, 0x04, 0x08,//up INDEX 24 - 0x10, 0x20, 0x7E, 0x20, 0x10,//down INDEX 25 - 0x08, 0x08, 0x2A, 0x1C, 0x08, - 0x08, 0x1C, 0x2A, 0x08, 0x08, - 0x1E, 0x10, 0x10, 0x10, 0x10, - 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, - 0x30, 0x38, 0x3E, 0x38, 0x30, - 0x06, 0x0E, 0x3E, 0x0E, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x5F, 0x00, 0x00, - 0x00, 0x07, 0x00, 0x07, 0x00, - 0x14, 0x7F, 0x14, 0x7F, 0x14, - 0x24, 0x2A, 0x7F, 0x2A, 0x12, - 0x23, 0x13, 0x08, 0x64, 0x62, - 0x36, 0x49, 0x56, 0x20, 0x50, - 0x00, 0x08, 0x07, 0x03, 0x00, - 0x00, 0x1C, 0x22, 0x41, 0x00, - 0x00, 0x41, 0x22, 0x1C, 0x00, - 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, - 0x08, 0x08, 0x3E, 0x08, 0x08, - 0x00, 0x80, 0x70, 0x30, 0x00, - 0x08, 0x08, 0x08, 0x08, 0x08, - 0x00, 0x00, 0x60, 0x60, 0x00, - 0x20, 0x10, 0x08, 0x04, 0x02, - 0x3E, 0x51, 0x49, 0x45, 0x3E, - 0x00, 0x42, 0x7F, 0x40, 0x00, - 0x72, 0x49, 0x49, 0x49, 0x46, - 0x21, 0x41, 0x49, 0x4D, 0x33, - 0x18, 0x14, 0x12, 0x7F, 0x10, - 0x27, 0x45, 0x45, 0x45, 0x39, - 0x3C, 0x4A, 0x49, 0x49, 0x31, - 0x41, 0x21, 0x11, 0x09, 0x07, - 0x36, 0x49, 0x49, 0x49, 0x36, - 0x46, 0x49, 0x49, 0x29, 0x1E, - 0x00, 0x00, 0x14, 0x00, 0x00, - 0x00, 0x40, 0x34, 0x00, 0x00, - 0x00, 0x08, 0x14, 0x22, 0x41, - 0x14, 0x14, 0x14, 0x14, 0x14, - 0x00, 0x41, 0x22, 0x14, 0x08, - 0x02, 0x01, 0x59, 0x09, 0x06, - 0x3E, 0x41, 0x5D, 0x59, 0x4E, - 0x7C, 0x12, 0x11, 0x12, 0x7C, - 0x7F, 0x49, 0x49, 0x49, 0x36, - 0x3E, 0x41, 0x41, 0x41, 0x22,//C - 0x7F, 0x41, 0x41, 0x41, 0x3E,//D - 0x7F, 0x49, 0x49, 0x49, 0x41,//E - 0x7F, 0x09, 0x09, 0x09, 0x01,//F - 0x3E, 0x41, 0x41, 0x51, 0x73, - 0x7F, 0x08, 0x08, 0x08, 0x7F, - 0x00, 0x41, 0x7F, 0x41, 0x00, - 0x20, 0x40, 0x41, 0x3F, 0x01, - 0x7F, 0x08, 0x14, 0x22, 0x41, - 0x7F, 0x40, 0x40, 0x40, 0x40, - 0x7F, 0x02, 0x1C, 0x02, 0x7F, - 0x7F, 0x04, 0x08, 0x10, 0x7F, - 0x3E, 0x41, 0x41, 0x41, 0x3E, - 0x7F, 0x09, 0x09, 0x09, 0x06, - 0x3E, 0x41, 0x51, 0x21, 0x5E, - 0x7F, 0x09, 0x19, 0x29, 0x46, - 0x26, 0x49, 0x49, 0x49, 0x32, - 0x03, 0x01, 0x7F, 0x01, 0x03, - 0x3F, 0x40, 0x40, 0x40, 0x3F, - 0x1F, 0x20, 0x40, 0x20, 0x1F, - 0x3F, 0x40, 0x38, 0x40, 0x3F, - 0x63, 0x14, 0x08, 0x14, 0x63, - 0x03, 0x04, 0x78, 0x04, 0x03, - 0x61, 0x59, 0x49, 0x4D, 0x43, - 0x00, 0x7F, 0x41, 0x41, 0x41, - 0x02, 0x04, 0x08, 0x10, 0x20, - 0x00, 0x41, 0x41, 0x41, 0x7F, - 0x04, 0x02, 0x01, 0x02, 0x04, - 0x40, 0x40, 0x40, 0x40, 0x40, - 0x00, 0x03, 0x07, 0x08, 0x00, - 0x20, 0x54, 0x54, 0x78, 0x40, - 0x7F, 0x28, 0x44, 0x44, 0x38, - 0x38, 0x44, 0x44, 0x44, 0x28, - 0x38, 0x44, 0x44, 0x28, 0x7F, - 0x38, 0x54, 0x54, 0x54, 0x18, - 0x00, 0x08, 0x7E, 0x09, 0x02, - 0x18, 0xA4, 0xA4, 0x9C, 0x78, - 0x7F, 0x08, 0x04, 0x04, 0x78, - 0x00, 0x44, 0x7D, 0x40, 0x00, - 0x20, 0x40, 0x40, 0x3D, 0x00, - 0x7F, 0x10, 0x28, 0x44, 0x00, - 0x00, 0x41, 0x7F, 0x40, 0x00, - 0x7C, 0x04, 0x78, 0x04, 0x78, - 0x7C, 0x08, 0x04, 0x04, 0x78, - 0x38, 0x44, 0x44, 0x44, 0x38, - 0xFC, 0x18, 0x24, 0x24, 0x18, - 0x18, 0x24, 0x24, 0x18, 0xFC, - 0x7C, 0x08, 0x04, 0x04, 0x08, - 0x48, 0x54, 0x54, 0x54, 0x24, - 0x04, 0x04, 0x3F, 0x44, 0x24, - 0x3C, 0x40, 0x40, 0x20, 0x7C, - 0x1C, 0x20, 0x40, 0x20, 0x1C, - 0x3C, 0x40, 0x30, 0x40, 0x3C, - 0x44, 0x28, 0x10, 0x28, 0x44, - 0x4C, 0x90, 0x90, 0x90, 0x7C, - 0x44, 0x64, 0x54, 0x4C, 0x44, - 0x00, 0x08, 0x36, 0x41, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, - 0x00, 0x41, 0x36, 0x08, 0x00, - 0x02, 0x01, 0x02, 0x04, 0x02, - 0x3C, 0x26, 0x23, 0x26, 0x3C, - 0x1E, 0xA1, 0xA1, 0x61, 0x12, - 0x3A, 0x40, 0x40, 0x20, 0x7A, - 0x38, 0x54, 0x54, 0x55, 0x59, - 0x21, 0x55, 0x55, 0x79, 0x41, - 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut - 0x21, 0x55, 0x54, 0x78, 0x40, - 0x20, 0x54, 0x55, 0x79, 0x40, - 0x0C, 0x1E, 0x52, 0x72, 0x12, - 0x39, 0x55, 0x55, 0x55, 0x59, - 0x39, 0x54, 0x54, 0x54, 0x59, - 0x39, 0x55, 0x54, 0x54, 0x58, - 0x00, 0x00, 0x45, 0x7C, 0x41, - 0x00, 0x02, 0x45, 0x7D, 0x42, - 0x00, 0x01, 0x45, 0x7C, 0x40, - 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut - 0xF0, 0x28, 0x25, 0x28, 0xF0, - 0x7C, 0x54, 0x55, 0x45, 0x00, - 0x20, 0x54, 0x54, 0x7C, 0x54, - 0x7C, 0x0A, 0x09, 0x7F, 0x49, - 0x32, 0x49, 0x49, 0x49, 0x32, - 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut - 0x32, 0x4A, 0x48, 0x48, 0x30, - 0x3A, 0x41, 0x41, 0x21, 0x7A, - 0x3A, 0x42, 0x40, 0x20, 0x78, - 0x00, 0x9D, 0xA0, 0xA0, 0x7D, - 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut - 0x3D, 0x40, 0x40, 0x40, 0x3D, - 0x3C, 0x24, 0xFF, 0x24, 0x24, - 0x48, 0x7E, 0x49, 0x43, 0x66, - 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, - 0xFF, 0x09, 0x29, 0xF6, 0x20, - 0xC0, 0x88, 0x7E, 0x09, 0x03, - 0x20, 0x54, 0x54, 0x79, 0x41, - 0x00, 0x00, 0x44, 0x7D, 0x41, - 0x30, 0x48, 0x48, 0x4A, 0x32, - 0x38, 0x40, 0x40, 0x22, 0x7A, - 0x00, 0x7A, 0x0A, 0x0A, 0x72, - 0x7D, 0x0D, 0x19, 0x31, 0x7D, - 0x26, 0x29, 0x29, 0x2F, 0x28, - 0x26, 0x29, 0x29, 0x29, 0x26, - 0x30, 0x48, 0x4D, 0x40, 0x20, - 0x38, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x38, - 0x2F, 0x10, 0xC8, 0xAC, 0xBA, - 0x2F, 0x10, 0x28, 0x34, 0xFA, - 0x00, 0x00, 0x7B, 0x00, 0x00, - 0x08, 0x14, 0x2A, 0x14, 0x22, - 0x22, 0x14, 0x2A, 0x14, 0x08, - 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code - 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block - 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block - 0x00, 0x00, 0x00, 0xFF, 0x00, - 0x10, 0x10, 0x10, 0xFF, 0x00, - 0x14, 0x14, 0x14, 0xFF, 0x00, - 0x10, 0x10, 0xFF, 0x00, 0xFF, - 0x10, 0x10, 0xF0, 0x10, 0xF0, - 0x14, 0x14, 0x14, 0xFC, 0x00, - 0x14, 0x14, 0xF7, 0x00, 0xFF, - 0x00, 0x00, 0xFF, 0x00, 0xFF, - 0x14, 0x14, 0xF4, 0x04, 0xFC, - 0x14, 0x14, 0x17, 0x10, 0x1F, - 0x10, 0x10, 0x1F, 0x10, 0x1F, - 0x14, 0x14, 0x14, 0x1F, 0x00, - 0x10, 0x10, 0x10, 0xF0, 0x00, - 0x00, 0x00, 0x00, 0x1F, 0x10, - 0x10, 0x10, 0x10, 0x1F, 0x10, - 0x10, 0x10, 0x10, 0xF0, 0x10, - 0x00, 0x00, 0x00, 0xFF, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0xFF, 0x10, - 0x00, 0x00, 0x00, 0xFF, 0x14, - 0x00, 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0x00, 0x1F, 0x10, 0x17, - 0x00, 0x00, 0xFC, 0x04, 0xF4, - 0x14, 0x14, 0x17, 0x10, 0x17, - 0x14, 0x14, 0xF4, 0x04, 0xF4, - 0x00, 0x00, 0xFF, 0x00, 0xF7, - 0x14, 0x14, 0x14, 0x14, 0x14, - 0x14, 0x14, 0xF7, 0x00, 0xF7, - 0x14, 0x14, 0x14, 0x17, 0x14, - 0x10, 0x10, 0x1F, 0x10, 0x1F, - 0x14, 0x14, 0x14, 0xF4, 0x14, - 0x10, 0x10, 0xF0, 0x10, 0xF0, - 0x00, 0x00, 0x1F, 0x10, 0x1F, - 0x00, 0x00, 0x00, 0x1F, 0x14, - 0x00, 0x00, 0x00, 0xFC, 0x14, - 0x00, 0x00, 0xF0, 0x10, 0xF0, - 0x10, 0x10, 0xFF, 0x10, 0xFF, - 0x14, 0x14, 0x14, 0xFF, 0x14, - 0x10, 0x10, 0x10, 0x1F, 0x00, - 0x00, 0x00, 0x00, 0xF0, 0x10, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0xFF, 0xFF, 0xFF, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xFF, 0xFF, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, - 0x38, 0x44, 0x44, 0x38, 0x44, - 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta - 0x7E, 0x02, 0x02, 0x06, 0x06, - 0x02, 0x7E, 0x02, 0x7E, 0x02, - 0x63, 0x55, 0x49, 0x41, 0x63, - 0x38, 0x44, 0x44, 0x3C, 0x04, - 0x40, 0x7E, 0x20, 0x1E, 0x20, - 0x06, 0x02, 0x7E, 0x02, 0x02, - 0x99, 0xA5, 0xE7, 0xA5, 0x99, - 0x1C, 0x2A, 0x49, 0x2A, 0x1C, - 0x4C, 0x72, 0x01, 0x72, 0x4C, - 0x30, 0x4A, 0x4D, 0x4D, 0x30, - 0x30, 0x48, 0x78, 0x48, 0x30, - 0xBC, 0x62, 0x5A, 0x46, 0x3D, - 0x3E, 0x49, 0x49, 0x49, 0x00, - 0x7E, 0x01, 0x01, 0x01, 0x7E, - 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, - 0x44, 0x44, 0x5F, 0x44, 0x44, - 0x40, 0x51, 0x4A, 0x44, 0x40, - 0x40, 0x44, 0x4A, 0x51, 0x40, - 0x00, 0x00, 0xFF, 0x01, 0x03, - 0xE0, 0x80, 0xFF, 0x00, 0x00, - 0x08, 0x08, 0x6B, 0x6B, 0x08, - 0x36, 0x12, 0x36, 0x24, 0x36, - 0x06, 0x0F, 0x09, 0x0F, 0x06, - 0x00, 0x00, 0x18, 0x18, 0x00, - 0x00, 0x00, 0x10, 0x10, 0x00, - 0x30, 0x40, 0xFF, 0x01, 0x01, - 0x00, 0x1F, 0x01, 0x01, 0x1E, - 0x00, 0x19, 0x1D, 0x17, 0x12, - 0x00, 0x3C, 0x3C, 0x3C, 0x3C, - 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP -}; - -/**************************************************************** - * Function Name : clearDisplay - * Description : Clear the display memory buffer - * Returns : NONE. - * Params : NONE. - ****************************************************************/ -void clearDisplay() -{ - memset(screen, 0x00, DISPLAY_BUFF_SIZE); -} - -/**************************************************************** - * Function Name : display_Init_seq - * Description : Performs SSD1306 OLED Initialization Sequence - * Returns : NONE. - * Params : NONE. - ****************************************************************/ -void display_Init_seq() -{ - /* Add the reset code, If needed */ - - /* Send display OFF command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_DISPLAY_OFF) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display OFF Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display OFF Command Failed\r\n"); -#endif - exit(1); - } - - /* Set display clock frequency */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_DISP_CLK) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display CLK Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display CLK Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display CLK command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_DISPCLK_DIV) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display CLK Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display CLK Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display multiplex */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_MULTIPLEX) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display MULT Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display MULT Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display MULT command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_MULT_DAT) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display MULT Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display MULT Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display OFFSET */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_DISP_OFFSET) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display OFFSET Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display OFFSET Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display OFFSET command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_DISP_OFFSET_VAL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display OFFSET Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display OFFSET Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display START LINE - Check this command if something weird happens */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_DISP_START_LINE) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display START LINE Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display START LINE Command Failed\r\n"); -#endif - exit(1); - } - - /* Enable CHARGEPUMP*/ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_CONFIG_CHARGE_PUMP) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display CHARGEPUMP Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display CHARGEPUMP Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display CHARGEPUMP command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_CHARGE_PUMP_EN) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display CHARGEPUMP Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display CHARGEPUMP Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display MEMORYMODE */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_MEM_ADDR_MODE) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display MEMORYMODE Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display MEMORYMODE Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display HORIZONTAL MEMORY ADDR MODE command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_HOR_MM) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display HORIZONTAL MEMORY ADDR MODE Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display HORIZONTAL MEMORY ADDR MODE Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display SEG_REMAP */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SEG_REMAP) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display SEG_REMAP Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display SEG_REMAP Command Failed\r\n"); -#endif - exit(1); - } - - /* Set display DIR */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_COMSCANDEC) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display DIR Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display DIR Command Failed\r\n"); -#endif - exit(1); - } - - /* Set display COM */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_COMPINS) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display COM Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display COM Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display COM command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_CONFIG_COM_PINS) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display COM Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display COM Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display CONTRAST */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_CONTRAST) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display CONTRAST Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display CONTRAST Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display CONTRAST command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_CONTRAST_VAL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display CONTRAST Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display CONTRAST Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display PRECHARGE */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_PRECHARGE) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display PRECHARGE Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display PRECHARGE Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display PRECHARGE command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_PRECHARGE_VAL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display PRECHARGE Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display PRECHARGE Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display VCOMH */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_VCOMDETECT) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display VCOMH Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display VCOMH Command Failed\r\n"); -#endif - exit(1); - } - - /* Send display VCOMH command parameter */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_VCOMH_VAL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display VCOMH Command Parameter Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display VCOMH Command Parameter Failed\r\n"); -#endif - exit(1); - } - - /* Set display ALL-ON */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_DISPLAYALLON_RESUME) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display ALL-ON Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display ALL-ON Command Failed\r\n"); -#endif - exit(1); - } - - /* Set display to NORMAL-DISPLAY */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_NORMAL_DISPLAY) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display NORMAL-DISPLAY Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display NORMAL-DISPLAY Command Failed\r\n"); -#endif - exit(1); - } - - /* Set display to DEACTIVATE_SCROLL */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_DEACTIVATE_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display DEACTIVATE_SCROLL Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display DEACTIVATE_SCROLL Command Failed\r\n"); -#endif - exit(1); - } - - /* Set display to TURN-ON */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_DISPLAYON) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display TURN-ON Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display TURN-ON Command Failed\r\n"); -#endif - exit(1); - } -} - -/**************************************************************** - * Function Name : transfer - * Description : Transfer the frame buffer onto the display - * Returns : NONE. - * Params : NONE. - ****************************************************************/ -void transfer() -{ - short loop_1 = 0, loop_2 = 0; - short index = 0x00; - for (loop_1 = 0; loop_1 < 1024; loop_1++) - { - chunk[0] = 0x40; - for(loop_2 = 1; loop_2 < 17; loop_2++) - chunk[loop_2] = screen[index++]; - if(i2c_multiple_writes(I2C_DEV_2.fd_i2c, 17, chunk) == 17) - { -#ifdef SSD1306_DBG - printf("Chunk written to RAM - Completed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Chunk written to RAM - Failed\r\n"); -#endif - exit(1); - } - - memset(chunk,0x00,17); - if(index == 1024) - break; - } -} - - -/**************************************************************** - * Function Name : Display - * Description : 1. Resets the column and page addresses. - * 2. Displays the contents of the memory buffer. - * Returns : NONE. - * Params : NONE. - * Note : Each new form can be preceded by a clearDisplay. - ****************************************************************/ -void Display() -{ - Init_Col_PG_addrs(SSD1306_COL_START_ADDR,SSD1306_COL_END_ADDR, - SSD1306_PG_START_ADDR,SSD1306_PG_END_ADDR); - transfer(); -} - -/**************************************************************** - * Function Name : Init_Col_PG_addrs - * Description : Sets the column and page, start and - * end addresses. - * Returns : NONE. - * Params : @col_start_addr: Column start address - * @col_end_addr: Column end address - * @pg_start_addr: Page start address - * @pg_end_addr: Page end address - ****************************************************************/ -void Init_Col_PG_addrs(unsigned char col_start_addr, unsigned char col_end_addr, - unsigned char pg_start_addr, unsigned char pg_end_addr) -{ - /* Send COLMN address setting command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_COL_ADDR) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display COLMN Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display COLMN Command Failed\r\n"); -#endif - exit(1); - } - - /* Set COLMN start address */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, col_start_addr) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display COLMN Start Address param Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display COLMN Start Address param Failed\r\n"); -#endif - exit(1); - } - - /* Set COLMN end address */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, col_end_addr) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display COLMN End Address param Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display COLMN End Address param Failed\r\n"); -#endif - exit(1); - } - - /* Send PAGE address setting command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_PAGEADDR) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display PAGE Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display PAGE Command Failed\r\n"); -#endif - exit(1); - } - - /* Set PAGE start address */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, pg_start_addr) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display PAGE Start Address param Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display PAGE Start Address param Failed\r\n"); -#endif - exit(1); - } - - /* Set PAGE end address */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, pg_end_addr) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display PAGE End Address param Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display PAGE End Address param Failed\r\n"); -#endif - exit(1); - } -} - -/**************************************************************** - * Function Name : setRotation - * Description : Set the display rotation - * Returns : NONE. - * Params : @x: Display rotation parameter - ****************************************************************/ -void setRotation(unsigned char x) -{ - _rotation = x & 3; - switch(_rotation) - { - case 0: - case 2: - _width = SSD1306_LCDWIDTH; - _height = SSD1306_LCDHEIGHT; - break; - case 1: - case 3: - _width = SSD1306_LCDHEIGHT; - _height = SSD1306_LCDWIDTH; - break; - } -} - -/**************************************************************** - * Function Name : startscrollright - * Description : Activate a right handed scroll for rows start - * through stop - * Returns : NONE. - * Params : @start: Start location - * @stop: Stop location - * HINT. : the display is 16 rows tall. To scroll the whole - * display, run: display.scrollright(0x00, 0x0F) - ****************************************************************/ -void startscrollright(unsigned char start, unsigned char stop) -{ - /* Send SCROLL horizontal right command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_RIGHT_HORIZONTAL_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display HORIZONTAL SCROLL RIGHT Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display HORIZONTAL SCROLL RIGHT Command Failed\r\n"); -#endif - exit(1); - } - - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_1 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_1 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, start) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_2 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_2 Passed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_3 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_3 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, stop) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_4 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_4 Passed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_5 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_5 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0xFF) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_6 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_6 Passed\r\n"); -#endif - exit(1); - } - /* Send SCROLL Activate command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_ACTIVATE_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("SCROLL Activate Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("SCROLL Activate Command Failed\r\n"); -#endif - exit(1); - } -} - -/**************************************************************** - * Function Name : startscrollleft - * Description : Activate a left handed scroll for rows start - * through stop - * Returns : NONE. - * Params : @start: Start location - * @stop: Stop location - * HINT. : the display is 16 rows tall. To scroll the whole - * display, run: display.scrollright(0x00, 0x0F) - ****************************************************************/ -void startscrollleft(unsigned char start, unsigned char stop) -{ - /* Send SCROLL horizontal left command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_LEFT_HORIZONTAL_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display HORIZONTAL SCROLL LEFT Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display HORIZONTAL SCROLL LEFT Command Failed\r\n"); -#endif - exit(1); - } - - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_1 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_1 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, start) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_2 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_2 Passed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_3 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_3 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, stop) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_4 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_4 Passed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_5 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_5 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0xFF) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_6 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("HORI_SR Param_6 Passed\r\n"); -#endif - exit(1); - } - /* Send SCROLL Activate command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_ACTIVATE_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("SCROLL Activate Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("SCROLL Activate Command Failed\r\n"); -#endif - exit(1); - } -} - -/**************************************************************** - * Function Name : startscrolldiagright - * Description : Activate a diagonal scroll for rows start - * through stop - * Returns : NONE. - * Params : @start: Start location - * @stop: Stop location - * HINT. : the display is 16 rows tall. To scroll the whole - * display, run: display.scrollright(0x00, 0x0F) - ****************************************************************/ -void startscrolldiagright(unsigned char start, unsigned char stop) -{ - /* Send SCROLL diagonal right command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_VERTICAL_SCROLL_AREA) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display DIAGONAL SCROLL RIGHT Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display DIAGONAL SCROLL RIGHT Command Failed\r\n"); -#endif - exit(1); - } - - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_1 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_1 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_LCDHEIGHT) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_2 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_2 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Cmd Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Cmd Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_3 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_3 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, start) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_4 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_4 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_5 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_5 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, stop) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_6 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_6 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x01) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_5 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_5 Failed\r\n"); -#endif - exit(1); - } - - /* Send SCROLL Activate command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_ACTIVATE_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("SCROLL Activate Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("SCROLL Activate Command Failed\r\n"); -#endif - exit(1); - } -} - -/**************************************************************** - * Function Name : startscrolldiagleft - * Description : Activate a diagonal scroll for rows start - * through stop - * Returns : NONE. - * Params : @start: Start location - * @stop: Stop location - * HINT. : the display is 16 rows tall. To scroll the whole - * display, run: display.scrollright(0x00, 0x0F) - ****************************************************************/ -void startscrolldiagleft(unsigned char start, unsigned char stop) -{ - /* Send SCROLL diagonal right command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_SET_VERTICAL_SCROLL_AREA) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Display DIAGONAL SCROLL RIGHT Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Display DIAGONAL SCROLL RIGHT Command Failed\r\n"); -#endif - exit(1); - } - - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_1 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_1 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_LCDHEIGHT) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_2 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_2 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("Cmd Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("Cmd Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_3 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_3 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, start) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_4 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_4 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x00) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_5 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_5 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, stop) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_6 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_6 Failed\r\n"); -#endif - exit(1); - } - - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, 0x01) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_5 Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("DIAG_SR Param_5 Failed\r\n"); -#endif - exit(1); - } - - /* Send SCROLL Activate command */ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_ACTIVATE_SCROLL) == I2C_TWO_BYTES) - { -#ifdef SSD1306_DBG - printf("SCROLL Activate Command Passed\r\n"); -#endif - } - else - { -#ifdef SSD1306_DBG - printf("SCROLL Activate Command Failed\r\n"); -#endif - exit(1); - } -} - -/**************************************************************** - * Function Name : stopscroll - * Description : Stop scrolling - * Returns : NONE. - * Params : NONE. - ****************************************************************/ -void stopscroll() -{ - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_DEACTIVATE_SCROLL) == I2C_TWO_BYTES) - { - printf("De-activate SCROLL Command Passed\r\n"); - } - else - { - printf("De-activate SCROLL Command Passed Failed\r\n"); - exit(1); - } -} - -/**************************************************************** - * Function Name : invertDisplay - * Description : Invert or Normalize the display - * Returns : NONE. - * Params : @i: 0x00 to Normal and 0x01 for Inverting - ****************************************************************/ -void invertDisplay(unsigned char i) -{ - if (i) - { - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_INVERTDISPLAY) == I2C_TWO_BYTES) - { - printf("Display Inverted - Passed\r\n"); - } - else - { - printf("Display Inverted - Failed\r\n"); - exit(1); - } - } - else - { - if(i2c_write_register(I2C_DEV_2.fd_i2c, SSD1306_CNTRL_CMD, SSD1306_NORMAL_DISPLAY) == I2C_TWO_BYTES) - { - printf("Display Normal - Passed\r\n"); - } - else - { - printf("Display Normal - Failed\r\n"); - exit(1); - } - } -} - -/**************************************************************** - * Function Name : drawPixel - * Description : Draw a pixel - * Returns : -1 on error and 0 on success - * Params : @x: X - Co-ordinate - * @y: Y - Co-ordinate - * @color: Color - ****************************************************************/ -signed char drawPixel(short x, short y, short color) -{ - /* Return if co-ordinates are out of display dimension's range */ - if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) - return -1; - switch(_rotation) - { - case 1: - SWAP(x,y); - x = _width - x - 1; - break; - case 2: - x = _width - x - 1; - y = _height - y - 1; - break; - case 3: - SWAP(x,y); - y = _height - y - 1; - break; - } - - /* x is the column */ - switch(color) - { - case WHITE: screen[x+ (y/8)*SSD1306_LCDWIDTH] |= (1 << (y&7)); break; - case BLACK: screen[x+ (y/8)*SSD1306_LCDWIDTH] &= ~(1 << (y&7)); break; - case INVERSE: screen[x+ (y/8)*SSD1306_LCDWIDTH] ^= (1 << (y&7)); break; - } - return 0; -} - -/**************************************************************** - * Function Name : writeLine - * Description : Bresenham's algorithm - * Returns : NONE - * Params : @x0: X0 Co-ordinate - * @y0: Y0 Co-ordinate - * @x1: X1 Co-ordinate - * @y1: Y1 Co-ordinate - * @color: Pixel color - ****************************************************************/ -void writeLine(short x0, short y0, short x1, short y1, short color) -{ - short steep = 0, dx = 0, dy = 0, err = 0, ystep = 0; - steep = abs(y1 - y0) > abs(x1 - x0); - if (steep) - { - SWAP(x0, y0); - SWAP(x1, y1); - } - - if (x0 > x1) - { - SWAP(x0, x1); - SWAP(y0, y1); - } - dx = x1 - x0; - dy = abs(y1 - y0); - - err = dx / 2; - - if (y0 < y1) - { - ystep = 1; - } else - { - ystep = -1; - } - - for (; x0<=x1; x0++) - { - if (steep) - { - drawPixel(y0, x0, color); - } else - { - drawPixel(x0, y0, color); - } - err -= dy; - if (err < 0) - { - y0 += ystep; - err += dx; - } - } -} - -/* (x,y) is topmost point; if unsure, calling function -should sort endpoints or call writeLine() instead */ -void drawFastVLine(short x, short y,short h, short color) -{ - //startWrite(); - writeLine(x, y, x, y+h-1, color); - //endWrite(); -} - -/* (x,y) is topmost point; if unsure, calling function -should sort endpoints or call writeLine() instead */ -void writeFastVLine(short x, short y, short h, short color) -{ - drawFastVLine(x, y, h, color); -} - -/* (x,y) is leftmost point; if unsure, calling function - should sort endpoints or call writeLine() instead */ -void drawFastHLine(short x, short y,short w, short color) -{ - //startWrite(); - writeLine(x, y, x+w-1, y, color); - //endWrite(); -} - -// (x,y) is leftmost point; if unsure, calling function -// should sort endpoints or call writeLine() instead -void writeFastHLine(short x, short y, short w, short color) -{ - drawFastHLine(x, y, w, color); -} - -/**************************************************************** - * Function Name : drawCircleHelper - * Description : Draw a.... - * Returns : NONE - * Params : @x: X Co-ordinate - * @y: Y Co-ordinate - * @w: Width - * @h: height - * @r: Corner radius - * @color: Pixel color - ****************************************************************/ -void drawCircleHelper( short x0, short y0, short r, unsigned char cornername, short color) -{ - short f = 1 - r; - short ddF_x = 1; - short ddF_y = -2 * r; - short x = 0; - short y = r; - - while (x= 0) - { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - if (cornername & 0x4) - { - drawPixel(x0 + x, y0 + y, color); - drawPixel(x0 + y, y0 + x, color); - } - if (cornername & 0x2) - { - drawPixel(x0 + x, y0 - y, color); - drawPixel(x0 + y, y0 - x, color); - } - if (cornername & 0x8) - { - drawPixel(x0 - y, y0 + x, color); - drawPixel(x0 - x, y0 + y, color); - } - if (cornername & 0x1) - { - drawPixel(x0 - y, y0 - x, color); - drawPixel(x0 - x, y0 - y, color); - } - } -} - -/**************************************************************** - * Function Name : drawLine - * Description : Draw line between two points - * Returns : NONE - * Params : @x0: X0 Starting X Co-ordinate - * @y0: Y0 Starting Y Co-ordinate - * @x1: X1 Ending X Co-ordinate - * @y1: Y1 Ending Y Co-ordinate - * @color: Pixel color - ****************************************************************/ -void drawLine(short x0, short y0, short x1, short y1, short color) -{ - if(x0 == x1) - { - if(y0 > y1) - SWAP(y0, y1); - drawFastVLine(x0, y0, y1 - y0 + 1, color); - } - else if(y0 == y1) - { - if(x0 > x1) SWAP(x0, x1); - drawFastHLine(x0, y0, x1 - x0 + 1, color); - } - else - { - //startWrite(); - writeLine(x0, y0, x1, y1, color); - //endWrite(); - } -} - -/**************************************************************** - * Function Name : drawRect - * Description : Draw a rectangle - * Returns : NONE - * Params : @x: Corner X Co-ordinate - * @y: Corner Y Co-ordinate - * @w: Width in pixels - * @h: Height in pixels - * @color: Pixel color - ****************************************************************/ -void drawRect(short x, short y, short w, short h, short color) -{ - //startWrite(); - writeFastHLine(x, y, w, color); - writeFastHLine(x, y+h-1, w, color); - writeFastVLine(x, y, h, color); - writeFastVLine(x+w-1, y, h, color); - //endWrite(); -} - -/**************************************************************** - * Function Name : fillRect - * Description : Fill the rectangle - * Returns : NONE - * Params : @x: Starting X Co-ordinate - * @y: Starting Y Co-ordinate - * @w: Width in pixels - * @h: Height in pixels - * @color: Pixel color - ****************************************************************/ -void fillRect(short x, short y, short w, short h, short color) -{ - short i = 0; - //startWrite(); - for (i=x; i= 0) - { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - drawPixel(x0 + x, y0 + y, color); - drawPixel(x0 - x, y0 + y, color); - drawPixel(x0 + x, y0 - y, color); - drawPixel(x0 - x, y0 - y, color); - drawPixel(x0 + y, y0 + x, color); - drawPixel(x0 - y, y0 + x, color); - drawPixel(x0 + y, y0 - x, color); - drawPixel(x0 - y, y0 - x, color); - } - //endWrite(); -} - -/**************************************************************** - * Function Name : fillCircleHelper - * Description : Used to do circles and roundrects - * Returns : NONE - * Params : @x: Center X Co-ordinate - * @y: Center Y Co-ordinate - * @r: Radius in pixels - * @cornername: Corner radius in pixels - * @color: Pixel color - ****************************************************************/ -void fillCircleHelper(short x0, short y0, short r, unsigned char cornername, short delta, short color) -{ - - short f = 1 - r; - short ddF_x = 1; - short ddF_y = -2 * r; - short x = 0; - short y = r; - - while (x= 0) - { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x; - - if (cornername & 0x1) - { - writeFastVLine(x0+x, y0-y, 2*y+1+delta, color); - writeFastVLine(x0+y, y0-x, 2*x+1+delta, color); - } - if (cornername & 0x2) - { - writeFastVLine(x0-x, y0-y, 2*y+1+delta, color); - writeFastVLine(x0-y, y0-x, 2*x+1+delta, color); - } - } -} - -/**************************************************************** - * Function Name : fillCircle - * Description : Fill the circle - * Returns : NONE - * Params : @x0: Center X Co-ordinate - * @y0: Center Y Co-ordinate - * @r: Radius in pixels - * @color: Pixel color - ****************************************************************/ -void fillCircle(short x0, short y0, short r, short color) -{ - //startWrite(); - writeFastVLine(x0, y0-r, 2*r+1, color); - fillCircleHelper(x0, y0, r, 3, 0, color); - //endWrite(); -} - -/**************************************************************** - * Function Name : drawTriangle - * Description : Draw a triangle - * Returns : NONE - * Params : @x0: Corner-1 X Co-ordinate - * @y0: Corner-1 Y Co-ordinate - * @x1: Corner-2 X Co-ordinate - * @y1: Corner-2 Y Co-ordinate - * @x2: Corner-3 X Co-ordinate - * @y2: Corner-3 Y Co-ordinate - * @color: Pixel color - ****************************************************************/ -void drawTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color) -{ - drawLine(x0, y0, x1, y1, color); - drawLine(x1, y1, x2, y2, color); - drawLine(x2, y2, x0, y0, color); -} - -/**************************************************************** - * Function Name : fillTriangle - * Description : Fill a triangle - * Returns : NONE - * Params : @x0: Corner-1 X Co-ordinate - * @y0: Corner-1 Y Co-ordinate - * @x1: Corner-2 X Co-ordinate - * @y1: Corner-2 Y Co-ordinate - * @x2: Corner-3 X Co-ordinate - * @y2: Corner-3 Y Co-ordinate - * @color: Pixel color - ****************************************************************/ -void fillTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color) -{ - short a, b, y, last, dx01, dy01, dx02, dy02, dx12, dy12; - int sa, sb; - - // Sort coordinates by Y order (y2 >= y1 >= y0) - if (y0 > y1) - { - SWAP(y0, y1); - SWAP(x0, x1); - } - if (y1 > y2) - { - SWAP(y2, y1); - SWAP(x2, x1); - } - if (y0 > y1) - { - SWAP(y0, y1); - SWAP(x0, x1); - } - - //startWrite(); - if(y0 == y2) - { // Handle awkward all-on-same-line case as its own thing - a = b = x0; - if(x1 < a) - a = x1; - else if(x1 > b) - b = x1; - if(x2 < a) - a = x2; - else if(x2 > b) - b = x2; - writeFastHLine(a, y0, b-a+1, color); - // endWrite(); - return; - } - - dx01 = x1 - x0; - dy01 = y1 - y0; - dx02 = x2 - x0; - dy02 = y2 - y0; - dx12 = x2 - x1; - dy12 = y2 - y1; - sa = 0; - sb = 0; - - // For upper part of triangle, find scanline crossings for segments - // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 - // is included here (and second loop will be skipped, avoiding a /0 - // error there), otherwise scanline y1 is skipped here and handled - // in the second loop...which also avoids a /0 error here if y0=y1 - // (flat-topped triangle). - if(y1 == y2) - last = y1; // Include y1 scanline - else - last = y1-1; // Skip it - - for(y=y0; y<=last; y++) - { - a = x0 + sa / dy01; - b = x0 + sb / dy02; - sa += dx01; - sb += dx02; - /* longhand: - a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); - b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); - */ - if(a > b) - SWAP(a,b); - writeFastHLine(a, y, b-a+1, color); - } - - // For lower part of triangle, find scanline crossings for segments - // 0-2 and 1-2. This loop is skipped if y1=y2. - sa = dx12 * (y - y1); - sb = dx02 * (y - y0); - for(; y<=y2; y++) - { - a = x1 + sa / dy12; - b = x0 + sb / dy02; - sa += dx12; - sb += dx02; - /* longhand: - a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); - b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); - */ - if(a > b) - SWAP(a,b); - writeFastHLine(a, y, b-a+1, color); - } - //endWrite(); -} - -/**************************************************************** - * Function Name : drawRoundRect - * Description : Draw a rounded rectangle - * Returns : NONE - * Params : @x: X Co-ordinate - * @y: Y Co-ordinate - * @w: Width - * @h: height - * @r: Corner radius - * @color: Pixel color - ****************************************************************/ -void drawRoundRect(short x, short y, short w, short h, short r, short color) -{ - // smarter version - //startWrite(); - writeFastHLine(x+r , y , w-2*r, color); // Top - writeFastHLine(x+r , y+h-1, w-2*r, color); // Bottom - writeFastVLine(x , y+r , h-2*r, color); // Left - writeFastVLine(x+w-1, y+r , h-2*r, color); // Right - // draw four corners - drawCircleHelper(x+r , y+r , r, 1, color); - drawCircleHelper(x+w-r-1, y+r , r, 2, color); - drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); - drawCircleHelper(x+r , y+h-r-1, r, 8, color); - //endWrite(); -} - -/**************************************************************** - * Function Name : fillRoundRect - * Description : Fill a rounded rectangle - * Returns : NONE - * Params : @x: X Co-ordinate - * @y: Y Co-ordinate - * @w: Width - * @h: height - * @r: Corner radius - * @color: Pixel color - ****************************************************************/ -void fillRoundRect(short x, short y, short w, short h, short r, short color) -{ - // smarter version - //startWrite(); - fillRect(x+r, y, w-2*r, h, color); - - // draw four corners - fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); - fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); - //endWrite(); -} - -/*---------------------------------------------------------------------------- - * BITMAP API's - ----------------------------------------------------------------------------*/ - -/**************************************************************** - * Function Name : drawBitmap - * Description : Draw a bitmap - * Returns : NONE - * Params : @x: X Co-ordinate - * @y: Y Co-ordinate - * @bitmap: bitmap to display - * @w: Width - * @h: height - * @color: Pixel color - ****************************************************************/ -void drawBitmap(short x, short y, const unsigned char bitmap[], short w, short h, short color) -{ - short byteWidth = 0, j = 0, i = 0; - unsigned char byte = 0; - byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte - - for(j=0; j 0) ? s : 1; -} - -/**************************************************************** - * Function Name : setTextColor - * Description : Set text color - * Returns : @c - Color - ****************************************************************/ -void setTextColor(short c) -{ - // For 'transparent' background, we'll set the bg - // to the same as fg instead of using a flag - textcolor = textbgcolor = c; -} - -/**************************************************************** - * Function Name : setTextWrap - * Description : Wraps the text - * Returns : @w - enable or disbale wrap - ****************************************************************/ -void setTextWrap(bool w) -{ - wrap = w; -} - -/**************************************************************** - * Function Name : getRotation - * Description : Get the rotation value - * Returns : NONE. - ****************************************************************/ -unsigned char getRotation() -{ - return _rotation; -} - -/**************************************************************** - * Function Name : drawBitmap - * Description : Draw a character - * Returns : NONE - * Params : @x: X Co-ordinate - * @y: Y Co-ordinate - * @c: Character - * @size: Scaling factor - * @bg: Background color - * @color: Pixel color - ****************************************************************/ -void drawChar(short x, short y, unsigned char c, short color, short bg, unsigned char size) -{ - unsigned char line = 0, *bitmap = NULL, w = 0, h = 0, xx = 0, yy = 0, bits = 0, bit = 0; - char i = 0, j = 0, xo = 0, yo = 0; - short bo = 0, xo16 = 0, yo16 = 0; - GFXglyphPtr glyph; - if(!gfxFont) - { - // 'Classic' built-in font - if((x >= _width) || (y >= _height) || ((x + 6 * size - 1) < 0) || ((y + 8 * size - 1) < 0)) - return; - - // Handle 'classic' charset behavior - if(!_cp437 && (c >= 176)) - c++; - - // Char bitmap = 5 columns - for(i=0; i<5; i++ ) - { - line = pgm_read_byte(&ssd1306_font5x7[c * 5 + i]); - for(j=0; j<8; j++, line >>= 1) - { - if(line & 1) - { - if(size == 1) - drawPixel(x+i, y+j, color); - else - fillRect(x+i*size, y+j*size, size, size, color); - } - else if(bg != color) - { - if(size == 1) - drawPixel(x+i, y+j, bg); - else - fillRect(x+i*size, y+j*size, size, size, bg); - } - } - } - - // If opaque, draw vertical line for last column - if(bg != color) - { - if(size == 1) - writeFastVLine(x+5, y, 8, bg); - else - fillRect(x+5*size, y, size, 8*size, bg); - } - - } - // Custom font - else - { - // Character is assumed previously filtered by write() to eliminate - // newlines, returns, non-printable characters, etc. Calling - // drawChar() directly with 'bad' characters of font may cause mayhem! - - c -= (unsigned char)pgm_read_byte(&gfxFont->first); - glyph = &(((GFXglyphT *)pgm_read_pointer(&gfxFont->glyph))[c]); - bitmap = (unsigned char *)pgm_read_pointer(&gfxFont->bitmap); - bo = pgm_read_word(&glyph->bitmapOffset); - w = pgm_read_byte(&glyph->width); - h = pgm_read_byte(&glyph->height); - xo = pgm_read_byte(&glyph->xOffset); - yo = pgm_read_byte(&glyph->yOffset); - - if(size > 1) - { - xo16 = xo; - yo16 = yo; - } - - // Todo: Add character clipping here - - // NOTE: THERE IS NO 'BACKGROUND' COLOR OPTION ON CUSTOM FONTS. - // THIS IS ON PURPOSE AND BY DESIGN. The background color feature - // has typically been used with the 'classic' font to overwrite old - // screen contents with new data. This ONLY works because the - // characters are a uniform size; it's not a sensible thing to do with - // proportionally-spaced fonts with glyphs of varying sizes (and that - // may overlap). To replace previously-drawn text when using a custom - // font, use the getTextBounds() function to determine the smallest - // rectangle encompassing a string, erase the area with fillRect(), - // then draw new text. This WILL unfortunately 'blink' the text, but - // is unavoidable. Drawing 'background' pixels will NOT fix this, - // only creates a new set of problems. Have an idea to work around - // this (a canvas object type for MCUs that can afford the RAM and - // displays supporting setAddrWindow() and pushColors()), but haven't - // implemented this yet. - for(yy=0; yy _width)) - { - // Off right? - cursor_x = 0; // Reset x to zero, - cursor_y += textsize * 8; // advance y one line - } - drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); - cursor_x += textsize * 6; // Advance x one char - } - - } - else - { - // Custom font - if(c == '\n') - { - cursor_x = 0; - cursor_y += (short)textsize *(unsigned char)pgm_read_byte(&gfxFont->yAdvance); - } - else if(c != '\r') - { - first = pgm_read_byte(&gfxFont->first); - if((c >= first) && (c <= (unsigned char)pgm_read_byte(&gfxFont->last))) - { - glyph = &(((GFXglyphT*)pgm_read_pointer(&gfxFont->glyph))[c - first]); - w = pgm_read_byte(&glyph->width); - h = pgm_read_byte(&glyph->height); - if((w > 0) && (h > 0)) - { - // Is there an associated bitmap? - xo = (char)pgm_read_byte(&glyph->xOffset); // sic - if(wrap && ((cursor_x + textsize * (xo + w)) > _width)) - { - cursor_x = 0; - cursor_y += (short)textsize *(unsigned char)pgm_read_byte(&gfxFont->yAdvance); - } - drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize); - } - cursor_x += (unsigned char)pgm_read_byte(&glyph->xAdvance) * (short)textsize; - } - } - } - return 1; -} - -/**************************************************************** - * Function Name : print - * Description : Base function for printing strings - * Returns : No. of characters printed - * Params : @buffer: Ptr to buffer containing the string - * @size: Length of the string. - ****************************************************************/ -short print(const unsigned char *buffer, short size) -{ - short n = 0; - while(size--) - { - if(oled_write(*buffer++)) - n++; - else - break; - } - return (n); -} - -/**************************************************************** - * Function Name : print_str - * Description : Print strings - * Returns : No. of characters printed - * Params : @strPtr: Ptr to buffer containing the string - ****************************************************************/ -short print_str(const unsigned char *strPtr) -{ - return print(strPtr, strlen(strPtr)); -} - -/**************************************************************** - * Function Name : println - * Description : Move to next line - * Returns : No. of characters printed - * Params : NONE. - ****************************************************************/ -short println() -{ - return print_str("\r\n"); -} - -/**************************************************************** - * Function Name : print_strln - * Description : Print strings and move to next line - * Returns : No. of characters printed - * Params : @strPtr: Ptr to buffer containing the string - ****************************************************************/ -short print_strln(const unsigned char *strPtr) -{ - short n = 0; - n = print(strPtr, strlen(strPtr)); - n += print_str("\r\n"); - return (n); -} - -/*---------------------------------------------------------------------------- - * NUMBERS HANDLING API's - ----------------------------------------------------------------------------*/ - -/**************************************************************** - * Function Name : printNumber - * Description : Base function to print unsigned numbers - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber(unsigned long n, unsigned char base) -{ - unsigned long m = 0; - char c = 0; - char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. - char *str = &buf[sizeof(buf) - 1]; - - *str = '\0'; - - // prevent crash if called with base == 1 - if(base < 2) - base = 10; - do - { - m = n; - n /= base; - c = m - base * n; - *--str = c < 10 ? c + '0' : c + 'A' - 10; - } - while(n); - //return oled_write((unsigned char)str); - return print_str(str); -} - -/**************************************************************** - * Function Name : printNumber_UL - * Description : Print unsigned long data types - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_UL(unsigned long n, int base) -{ - if(base == 0) - return oled_write(n); - else - return printNumber(n, base); -} - -/**************************************************************** - * Function Name : printNumber_UL_ln - * Description : Print unsigned long & advance to next line - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_UL_ln(unsigned long num, int base) -{ - short n = 0; - n = printNumber(num, base); - n += println(); - return (n); -} - -/**************************************************************** - * Function Name : printNumber_UI - * Description : Print unsigned int data types - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_UI(unsigned int n, int base) -{ - return printNumber((unsigned long) n, base); -} - -/**************************************************************** - * Function Name : printNumber_UI_ln - * Description : Print unsigned int & advance to next line - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_UI_ln(unsigned int n, int base) -{ - short a = 0; - a = printNumber((unsigned long) n, base); - a += println(); - return (a); -} - -/**************************************************************** - * Function Name : printNumber_UC - * Description : Print unsigned char data types - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_UC(unsigned char b, int base) -{ - return printNumber((unsigned long) b, base); -} - -/**************************************************************** - * Function Name : printNumber_UC_ln - * Description : Print unsigned char & advance to next line - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_UC_ln(unsigned char b, int base) -{ - short n = 0; - n = printNumber((unsigned long) b, base); - n += println(); - return (n); -} - -/**************************************************************** - * Function Name : printNumber_L - * Description : Print Long data types - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_L(long n, int base) -{ - int t = 0; - if(base == 0) - { - return oled_write(n); - } - else if(base == 10) - { - if(n < 0) - { - t = oled_write('-'); - n = -n; - return printNumber(n, 10) + t; - } - return printNumber(n, 10); - } - else - { - return printNumber(n, base); - } -} - -/**************************************************************** - * Function Name : printNumber_UC_ln - * Description : Print long & advance to next line - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_L_ln(long num, int base) -{ - short n = 0; - n = printNumber_L(num, base); - n += println(); - return n; -} - -/**************************************************************** - * Function Name : printNumber_I - * Description : Print int data types - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_I(int n, int base) -{ - return printNumber_L((long) n, base); -} - -/**************************************************************** - * Function Name : printNumber_I_ln - * Description : Print int & advance to next line - * Returns : No. of characters printed - * Params : @n: Number - * @base: Base e.g. HEX, BIN... - ****************************************************************/ -short printNumber_I_ln(int n, int base) -{ - short a = 0; - a = printNumber_L((long) n, base); - a += println(); - return a; -} - -/**************************************************************** - * Function Name : printFloat - * Description : Print floating Pt. No's. - * Returns : No. of characters printed - * Params : @n: Number - * @digits: Resolution - ****************************************************************/ -short printFloat(double number, unsigned char digits) -{ - unsigned char i = 0; - short n = 0; - unsigned long int_part = 0; - double remainder = 0.0; - int toPrint = 0; - - // Round correctly so that print(1.999, 2) prints as "2.00" - double rounding = 0.5; - - if(isnan(number)) - return print_str("nan"); - if(isinf(number)) - return print_str("inf"); - if(number > 4294967040.0) - return print_str("ovf"); // constant determined empirically - if(number < -4294967040.0) - return print_str("ovf"); // constant determined empirically - - // Handle negative numbers - if(number < 0.0) - { - n += oled_write('-'); - number = -number; - } - - - for(i = 0; i < digits; ++i) - rounding /= 10.0; - - number += rounding; - - // Extract the integer part of the number and print it - int_part = (unsigned long) number; - remainder = number - (double) int_part; - n += printNumber_UL(int_part,DEC); - - // Print the decimal point, but only if there are digits beyond - if(digits > 0) - { - n += print_str("."); - } - - // Extract digits from the remainder one at a time - while(digits-- > 0) - { - remainder *= 10.0; - toPrint = (int)remainder; - n += printNumber_I(toPrint,DEC); - remainder -= toPrint; - } - return n; -} - -/**************************************************************** - * Function Name : printFloat_ln - * Description : Print floating Pt. No and advance to next line - * Returns : No. of characters printed - * Params : @n: Number - * @digits: Resolution - ****************************************************************/ -short printFloat_ln(double num, int digits) -{ - short n = 0; - n = printFloat(num, digits); - n += println(); - return n; -} diff --git a/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h b/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h deleted file mode 100644 index 9becaf4a0..000000000 --- a/luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * MIT License - -Copyright (c) 2017 DeeplyEmbedded - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - * SSD1306_OLED.h - * - * Created on : Sep 21, 2017 - * Author : Vinay Divakar - * Website : www.deeplyembedded.org - */ - -#ifndef SSD1306_OLED_H_ -#define SSD1306_OLED_H_ - -/* Lib's */ -#include - -/* Find Min and Max - MACROS */ -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -/* I2C Address of SSD1306 */ -#define SSD1306_OLED_ADDR 0x3C -#define DISPLAY_BUFF_SIZE (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8) - -/* COLOR MACROS */ -#define WHITE 1 -#define BLACK 0 -#define INVERSE 2 - -/* Number output format */ -#define DEC 10 -#define HEX 16 -#define OCT 8 -#define BIN 2 -#define DEFAULT 0 - -/*D/C# bit is '0' indicating that following - * byte is a command. '1' is for data - */ -#define SSD1306_CNTRL_CMD 0x00 -#define SSD1306_CNTRL_DATA 0x40 - - -/*-----------------------Enable the WxL of the Display ---------------------------*/ -//#define SSD1306_128_64 -#define SSD1306_128_32 -//#define SSD1306_96_16 -/*--------------------------------------------------------------------------------*/ - -/* LCD HxW i.e. 64x128 || WxL i.e. 128x64 */ -#if defined SSD1306_128_64 -#define SSD1306_LCDWIDTH 128 -#define SSD1306_LCDHEIGHT 64 -#endif -#if defined SSD1306_128_32 - #define SSD1306_LCDWIDTH 128 - #define SSD1306_LCDHEIGHT 32 -#endif -#if defined SSD1306_96_16 - #define SSD1306_LCDWIDTH 96 - #define SSD1306_LCDHEIGHT 16 -#endif - -/* SSD1306 Commands */ -#define SSD1306_DISPLAY_OFF 0xAE -#define SSD1306_SET_DISP_CLK 0xD5 -#define SSD1306_SET_MULTIPLEX 0xA8 -#define SSD1306_SET_DISP_OFFSET 0xD3 -#define SSD1306_SET_DISP_START_LINE 0x40// | 0x00) -#define SSD1306_CONFIG_CHARGE_PUMP 0x8D -#define SSD1306_SET_MEM_ADDR_MODE 0x20 -#define SSD1306_SEG_REMAP (0xA0 | 0x01) //Rotate 180 Degrees -#define SSD1306_SET_COMSCANDEC 0xC8 -#define SSD1306_SET_COMPINS 0xDA -#define SSD1306_SET_CONTRAST 0x81 -#define SSD1306_SET_PRECHARGE 0xD9 -#define SSD1306_SET_VCOMDETECT 0xDB -#define SSD1306_DISPLAYALLON_RESUME 0xA4 -#define SSD1306_NORMAL_DISPLAY 0xA6 -#define SSD1306_DISPLAYON 0xAF -#define SSD1306_SET_COL_ADDR 0x21 -#define SSD1306_PAGEADDR 0x22 -#define SSD1306_INVERT_DISPLAY 0x01 -#define SSD1306_NORMALIZE_DISPLAY 0x00 - -/* SDD1306 Scroll Commands */ -#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 -#define SSD1306_ACTIVATE_SCROLL 0x2F -#define SSD1306_DEACTIVATE_SCROLL 0x2E -#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26 -#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27 -#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 -#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A -#define SSD1306_INVERTDISPLAY 0xA7 - -/* SSD1306 Configuration Commands */ -#define SSD1306_DISPCLK_DIV 0x80 -#if defined SSD1306_128_64 -#define SSD1306_MULT_64 0x3F -#endif -#if defined SSD1306_128_32 - #define SSD1306_MULT_64 0x1F -#endif -#define SSD1306_MULT_64 0x1F -#define SSD1306_DISP_OFFSET_VAL 0x00 -#define SSD1306_COL_START_ADDR 0x00 //Reset to = 0 -#define SSD1306_COL_END_ADDR (SSD1306_LCDWIDTH - 1) //Reset to = 127 -#define SSD1306_PG_START_ADDR 0x00 -#define SSD1306_PG_END_ADDR 7 -#define SSD1306_CHARGE_PUMP_EN 0x14 -#if defined SSD1306_128_64 -#define SSD1306_CONFIG_COM_PINS 0x12 -#endif -#if defined SSD1306_128_32 - #define SSD1306_CONFIG_COM_PINS 0x02 -#endif -#define SSD1306_CONTRAST_VAL 0xCF //207 -#define SSD1306_PRECHARGE_VAL 0xF1 -#define SSD1306_VCOMH_VAL 0x40 -#define SSD1306_MULT_DAT (SSD1306_LCDHEIGHT - 1) -#define SSD1306_HOR_MM 0x00 - -/*SSD1306 Display API's */ -extern void clearDisplay(); -extern void display_Init_seq(); -extern void Display(); -extern void Init_Col_PG_addrs(unsigned char col_start_addr, unsigned char col_end_addr, - unsigned char pg_start_addr, unsigned char pg_end_addr); -extern void setRotation(unsigned char x); -extern void startscrollright(unsigned char start, unsigned char stop); -extern void startscrollleft(unsigned char start, unsigned char stop); -extern void startscrolldiagright(unsigned char start, unsigned char stop); -extern void startscrolldiagleft(unsigned char start, unsigned char stop); -extern void stopscroll(); -extern void setCursor(short x, short y); -extern short getCursorX(); -extern short getCursorY(); -extern unsigned char getRotation(); -extern void invertDisplay(unsigned char i); - -/*SSD1306 Graphics Handling API's */ -extern signed char drawPixel(short x, short y, short color); -extern void writeLine(short x0, short y0, short x1, short y1, short color); -extern void drawCircleHelper( short x0, short y0, short r, unsigned char cornername, short color); -extern void drawLine(short x0, short y0, short x1, short y1, short color); -extern void drawRect(short x, short y, short w, short h, short color); -extern void fillRect(short x, short y, short w, short h, short color); -extern void drawCircle(short x0, short y0, short r, short color); -extern void fillCircleHelper(short x0, short y0, short r, unsigned char cornername, short delta, short color); -extern void fillCircle(short x0, short y0, short r, short color); -extern void drawTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color); -extern void fillTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color); -extern void drawRoundRect(short x, short y, short w, short h, short r, short color); -extern void fillRoundRect(short x, short y, short w, short h, short r, short color); -extern void drawBitmap(short x, short y, const unsigned char bitmap[], short w, short h, short color); -extern short oled_write(unsigned char c); - -/*SSD1306 Text and Character Handling API's */ -extern void setTextSize(unsigned char s); -extern void setTextColor(short c); -extern void setTextWrap(bool w); -extern void drawChar(short x, short y, unsigned char c, short color, short bg, unsigned char size); -extern short print_str(const unsigned char *strPtr); -extern short println(); -extern short print_strln(const unsigned char *strPtr); - -/*SSD1306 Number Handling API's */ -extern short printNumber(unsigned long n, unsigned char base); -extern short printNumber_UL(unsigned long n, int base); -extern short printNumber_UL_ln(unsigned long num, int base); -extern short printNumber_UI(unsigned int n, int base); -extern short printNumber_UI_ln(unsigned int n, int base); -extern short printNumber_UC(unsigned char b, int base); -extern short printNumber_UC_ln(unsigned char b, int base); -extern short printNumber_L(long n, int base); -extern short printNumber_L_ln(long num, int base); -extern short printNumber_I(int n, int base); -extern short printNumber_I_ln(int n, int base); -extern short printFloat(double number, unsigned char digits); -extern short printFloat_ln(double num, int digits); -#endif /* SSD1306_OLED_H_ */ - diff --git a/luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h b/luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h deleted file mode 100644 index e66128a88..000000000 --- a/luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _GFXFONT_H_ -#define _GFXFONT_H_ - -typedef struct { // Data stored PER GLYPH - unsigned short bitmapOffset; // Pointer into GFXfont->bitmap - unsigned char width, height; // Bitmap dimensions in pixels - unsigned char xAdvance; // Distance to advance cursor (x axis) - char xOffset, yOffset; // Dist from cursor pos to UL corner -} GFXglyphT, *GFXglyphPtr; - -typedef struct { // Data stored for FONT AS A WHOLE: - unsigned char *bitmap; // Glyph bitmaps, concatenated - GFXglyphPtr glyph; // Glyph array - unsigned char first, last; // ASCII extents - unsigned char yAdvance; // Newline distance (y axis) -} GFXfontT, *GFXfontPtr; - -#endif // _GFXFONT_H_ diff --git a/v2ray-geodata/Makefile b/v2ray-geodata/Makefile index 2bb144879..7efb8eaeb 100644 --- a/v2ray-geodata/Makefile +++ b/v2ray-geodata/Makefile @@ -12,13 +12,13 @@ PKG_MAINTAINER:=Tianling Shen include $(INCLUDE_DIR)/package.mk -GEOIP_VER:=202308170035 +GEOIP_VER:=202308240036 GEOIP_FILE:=geoip.dat.$(GEOIP_VER) define Download/geoip URL:=https://github.com/v2fly/geoip/releases/download/$(GEOIP_VER)/ URL_FILE:=geoip.dat FILE:=$(GEOIP_FILE) - HASH:=6570442896a2387a49c4b757f172c12ad01d0523aa1df98f941f72e1c1468083 + HASH:=1982be239f54a97d26803bd8892365cb27af27a63256e85293f159f77ef49273 endef GEOSITE_VER:=20230821154916