Merge commit '8d24829f67ea5ed5b020111ea34b98ecc8f68f29' as 'components/u8g2'

This commit is contained in:
Alex Mikhalev 2019-01-15 20:36:08 -08:00
commit b8e2f8670e
2763 changed files with 17674741 additions and 0 deletions

View File

@ -0,0 +1,92 @@
set(COMPONENT_ADD_INCLUDEDIRS csrc)
set(COMPONENT_SRCS "csrc/u8x8_setup.c"
"csrc/u8x8_u8toa.c"
"csrc/u8x8_d_ssd1306_96x16.c"
"csrc/u8g2_d_memory.c"
"csrc/u8g2_selection_list.c"
"csrc/u8g2_hvline.c"
"csrc/u8x8_d_ssd1306_128x64_noname.c"
"csrc/u8x8_message.c"
"csrc/u8x8_d_ssd1306_48x64.c"
"csrc/u8x8_d_ssd1305.c"
"csrc/u8g2_kerning.c"
"csrc/u8x8_input_value.c"
"csrc/u8x8_d_st7586s_s028hn118a.c"
"csrc/u8g2_polygon.c"
"csrc/u8x8_d_uc1604.c"
"csrc/u8x8_d_ssd1306_128x32.c"
"csrc/u8x8_d_ssd1322.c"
"csrc/u8x8_d_sbn1661.c"
"csrc/u8g2_input_value.c"
"csrc/u8x8_8x8.c"
"csrc/u8x8_debounce.c"
"csrc/u8x8_d_uc1638.c"
"csrc/u8g2_setup.c"
"csrc/u8x8_d_ist3020.c"
"csrc/u8x8_display.c"
"csrc/u8x8_d_ssd1317.c"
"csrc/u8x8_d_ks0108.c"
"csrc/u8g2_box.c"
"csrc/u8x8_selection_list.c"
"csrc/u8x8_d_ssd1326.c"
"csrc/u8x8_d_st75256.c"
"csrc/u8x8_d_ssd1309.c"
"csrc/u8x8_byte.c"
"csrc/u8x8_d_ssd1607_200x200.c"
"csrc/u8x8_d_pcd8544_84x48.c"
"csrc/u8log.c"
"csrc/u8x8_d_sh1107.c"
"csrc/u8log_u8x8.c"
"csrc/u8g2_message.c"
"csrc/u8x8_d_uc1610.c"
"csrc/u8x8_d_sh1106_72x40.c"
"csrc/u8g2_line.c"
"csrc/u8g2_intersection.c"
"csrc/u8g2_fonts.c"
"csrc/u8x8_d_sh1106_64x32.c"
"csrc/u8x8_d_sed1330.c"
"csrc/u8x8_d_pcf8814_hx1230.c"
"csrc/u8x8_d_il3820_296x128.c"
"csrc/u8x8_d_uc1701_dogs102.c"
"csrc/u8g2_cleardisplay.c"
"csrc/u8x8_d_ssd1325.c"
"csrc/u8g2_font.c"
"csrc/u8x8_d_uc1601.c"
"csrc/u8x8_d_pcf8812.c"
"csrc/u8x8_cad.c"
"csrc/u8x8_d_uc1611.c"
"csrc/u8x8_string.c"
"csrc/u8g2_ll_hvline.c"
"csrc/u8x8_fonts.c"
"csrc/u8x8_d_ld7032_60x32.c"
"csrc/u8x8_d_max7219.c"
"csrc/u8x8_d_st7588.c"
"csrc/u8x8_d_ssd1606_172x72.c"
"csrc/u8x8_d_st7586s_erc240160.c"
"csrc/u8x8_d_stdio.c"
"csrc/u8x8_d_sh1122.c"
"csrc/u8log_u8g2.c"
"csrc/u8g2_circle.c"
"csrc/u8x8_d_ssd1306_64x48.c"
"csrc/u8g2_buffer.c"
"csrc/u8g2_bitmap.c"
"csrc/u8x8_d_lc7981.c"
"csrc/u8x8_d_st7920.c"
"csrc/u8x8_d_t6963.c"
"csrc/u8x8_d_st7567.c"
"csrc/u8x8_d_ls013b7dh03.c"
"csrc/u8x8_d_ssd1327.c"
"csrc/u8x8_d_sh1108.c"
"csrc/u8x8_gpio.c"
"csrc/u8x8_d_uc1608.c"
"csrc/u8x8_d_uc1617.c"
"csrc/u8x8_d_ssd1329.c"
"csrc/u8x8_d_ssd1306_64x32.c"
"csrc/u8g2_d_setup.c"
"csrc/u8x8_d_uc1701_mini12864.c"
"csrc/u8x8_u16toa.c"
"csrc/u8x8_d_a2printer.c"
"csrc/u8x8_d_st7565.c")
set(COMPONENT_NAME ".")
register_component()

213
components/u8g2/ChangeLog Normal file
View File

@ -0,0 +1,213 @@
https://github.com/olikraus/u8g2 ChangeLog
2016-04-30 v2.0.1 olikraus@gmail.com
* Support for DOGS102, ST7920, SSD1306
* Most graphics primitives are implemented
2016-05-15 v2.0.3 olikraus@gmail.com
* Support for Adafruit FeatherWing 128x32 OLED
* Added Wire.h support (I2C for SSD1306)
* Successfully tested with Adafruit ESP8266 Feather Board (HW+SW I2C)
* Successfully tested with Adafruit Feather M0 Basic Board (HW+SW I2C)
2016-06-12 v2.0.4 olikraus@gmail.com
* Support for ST7565
2016-06-25 v2.0.6 olikraus@gmail.com
* User interface functions
* Little Rook Chess ported
* ST7920 HW and SW SPI
2016-06-26 v2.0.7 olikraus@gmail.com
* drawLine
* GraphicsTest Example
2016-08-09 v2.1.5 olikraus@gmail.com
* T6963 Support
* Experimental Support for SSD1322 256x64
* A2 Thermoprinter Support
* Added several fonts from http://int10h.org/oldschool-pc-fonts/
* Added Arabic, Greek and Cyrillic fonts.
* Code cleanup (assert, spi modes, void * warning)
2016-08-17 v2.2.7 olikraus@gmail.com
* U8x8: Upscale by 2 (Issue 41)
* Fixed SSD1306 I2C procedures (mirror pixel in last tile column, issue 44)
* Experimental support für mini12864 (pull request)
* Use beginTransaction for SPI. This requires Arduino 1.6.0
2016-08-18 v2.3.2 olikraus@gmail.com
* MINI12874; Fixed HW Flip Mode (pull request 49)
* Fixed ST7920 HW SPI with very fast uC, issue 50
* Improved HW SPI for SH1106 and SSD1306 displays
* Fixed issue with missing fonts
2016-08-21 v2.4.1 olikraus@gmail.com
* Fixed HW SPI Modes (issue 52)
2016-10-01 v2.5.2 olikraus@gmail.com
* Added crox fonts (issue 57)
* Support for RA8835 (issue 45)
* Added support for SSD1322 and SSD1325
* Added DrawXBMP (AVR: Assume bitmap in PROGMEM)
* Added japanese fonts (issue 65)
2016-11-13 v2.6.3 olikraus@gmail.com
* Added support for UC1610 (EA DOGXL160)
* Use Wire.setClock() for improved HW I2C performance (issue 79). This
requires Arduino IDE 1.6.0 or higher.
* Added Thai Fonts (issue 73)
* Added support for "\n" in the print function for u8x8 (issue 74)
* Screen mirror option for U8g2 (issue 76)
* Added support for second wire interface (Constructor postfix 2ND_HW_I2C)
* Added support for UC1611 (EA DOGM240 and EA DOGXL240, issue 66)
2016-11-28 v2.7.5 olikraus@gmail.com
* Added support for 0.66" 64x48 SSD1306 OLED (issue 89)
* Support for UC1608 (issue 92)
* Speed improvements for SW SPI und 8080 mode (issues 87, 90 and 95)
* Fixed issue with ST7920 not using the optimized SW SPI procedures (issue 87)
* Direct buffer API (issue 93)
2016-12-11 v2.8.4 olikraus@gmail.com
* Increased contrast range for SSD1306 (issue 98)
* Support for KS0108 (issue 88)
* Support for UC1608 240x128 (issue 101)
* Speed improvement (issue 96)
2016-12-12 v2.8.5 olikraus@gmail.com
* Bugfix for issue 96 (issue 106)
2016-12-20 v2.9.1 olikraus@gmail.com
* Speed improvement for AVR/KS0108 (issue 104)
* Support for UC1604 (issue 111)
* Support for PCD8544/Nokia Display (issue 107)
* Change/fixed behavior of userInterfaceSelectionList (issue 112)
2016-12-23 v2.9.2 olikraus@gmail.com
* Reverted the setup for SSD1306_NONAME to the original setup (undo issue 98)
* Introduced SSD1306_VCOMH0 for the max range setup (issue 116)
2016-12-30 v2.10.1 olikraus@gmail.com
* ST7565 LM6059 Display (issue 123)
* SSD1606 eInk/ePaper Display (issue 100)
* Documentation updates
2017-01-08 v2.11.4 olikraus@gmail.com
* Support for LC7981 (issue 134)
* Support for PCF8812 (issue 135)
* Fixed wrong half-move notation in Little Rook Chess (issue 137)
* Support for ST7567, Pax Instruments GLCD Shield (issue 138)
* Support for NT7534 (issue 143)
* Support for SSD1327, Seeedstudio OLED (issue 145)
* Support for SSD1305 (issue 146)
* Support for DOGM132 (issue 147)
* Fixed a bug in the draw pixel procedure which appears in full buffer mode,
if the display width is not a multiple of 8 (issue 148)
* Added XOR mode (setDrawColor 2, issue 56)
2017-01-15 v2.12.6 olikraus@gmail.com
* Support for SSD1309 (issue 113)
* Enabled U8G2_HVLINE_SPEED_OPTIMIZATION (not sure why this was disabled)
* Improved speed for ST7920 (up to 40%, issue 151)
* Support for IST3020 (issue 153)
2017-02-07 v2.13.6 olikraus@gmail.com
* Support for ST7588 (issue 154)
* ESP8266: Avoid RAM copy of the fonts (issue 159)
* Support for SSD1607 (issue 133)
* Support for hardware pin remapping on the ESP8266 (issue 158)
* Bugfix for the KS0108 support (issue 168)
* More fonts: https://github.com/olikraus/u8g2/wiki/fntgrpnbp (issue 174)
2017-03-11 v2.14.7 olikraus@gmail.com
* Bugfix: setFont does no longer resets the reference position (issue 195)
* Support for ST7565 NHD C12864 (issue 186)
* Support for SSD1329 128x96 OLED (issue 208)
* Support for LC7981 240x128 (issue 193)
* Performance improvement for the ST7920 (issue 200)
2017-05-22 v2.15.2 olikraus@gmail.com
* Added setBitmapMode (pull request 220)
Warning: Default behavior of drawXBM has changed in this release.
* Increased SPI speed to 8MHz for SSD1306, SH1106 and SSD1322 (issue 215)
* Added some more examples (issue 216)
* Added Urdu, Bengali, Hebrew and Polish language fonts (issues 221, 246 and 266)
* Added more examples (issue 216)
* Updated code for NHD C12864 (issues 219 and 241)
* Improved speed for HW SPI with SSD13xx OLEDs (issue 215)
2017-08-12 v2.16.9 olikraus@gmail.com
* Fonts u8g2_font_unifont_t_korean1, u8g2_font_unifont_t_korean2 (issue 266)
* Added support for 64128N ST7565 based display (issue 292)
* Added extended fonts (_te, unicodes 32-701, issue 284)
* Added support for MAX7219 (issue 280)
* Performance optimization for SSD1322/25/27 (issue 302)
* Fixed setContrast for SSD1322 (issue 328)
* Support for 96x16 SSD1306 OLED (issue 295)
* Fixed OldStandard-Bold fonts (osb, issue 306)
* Support for SED1520/SBN1661 (issue 324)
2017-09-10 v2.17.11 olikraus@gmail.com
* Additional _m_ and _h_ symbol fonts (issue 335)
* Added parallel interfaces for several UC16xx devices (issue 339)
* Support for IL3820, WaveShare 2.9" e-paper (issues 318 & 347)
* Improved debounce algorithm (issue 338)
* Power save mode for SSD1607 device (issue 352)
2017-09-30 v2.18.13 olikraus@gmail.com
* Support for ST7567_JLX12864 (issue 365)
* Support for UC1611 (no "s") (issue 339)
* Fixed several issues related to the _F_ (full buffer) mode (issue 370)
2017-10-13 v2.19.8 olikraus@gmail.com
* Support for UC1601 (issue 378)
* Support for ESP32 I2C pin remapping (issue 377)
* Support for ST75256 (SPI), JLX256128, JLX172104 (issue 163)
* Added uw-ttyp0 fonts (issue 349)
2017-12-09 v2.20.13 olikraus@gmail.com
* Bugfix for drawBitmap (issue 391)
* I2C support for ST75256 (issue 384)
* Support for SSD1327 128x128 display (issue 397)
* Support for ST75256 JLX25664 display (issue 399)
* Added keywords.txt (issue 402)
* Experimental support for SSD1326 (issue 398)
* Experimental alternative COM config for SSD1306 128x64 (issue 408)
* New SH1106 init sequence (SH1106_WINSTAR, issue 316)
* Support for SSD1322 NHD 128x64 (issue 412)
* Fixed profont17 (issue 438)
2018-02-18 v2.21.8 olikraus@gmail.com
* Support for SH1107 (issue 501)
* Support for HX1230 (issue 469)
* Bugfix for displays with display height not a multiple of 8 (issue 469)
* FontUsage demo for full buffer mode (issue 490)
* Added 1x2 (double height) draw procedures to U8x8 (issue 474)
With this feature a 128x32 display can replace a 16x2 Char LCD.
* New constructor for the Good Display 200x200 eInk (issue 454)
* Update for the ST7920 device for more stable output (issue 487)
* Double height (2x1) chars for U8x8 API (issue 474)
* Excluded I2C for several ATMega uC which do not have HW I2C (issue 508)
* Fixed UC1610 contrast command (issue 428)
* Added WQY Chinese fonts at sizes 12, 13, 14, 15 and 16
including gb2312 support (issue 455)
* Added new full buffer demo for the Chinese fonts (Shennong.ino, issue #455)
* Added siji icon font u8g2_font_siji_t_6x10 (issue 451)
2018-04-30 v2.22.18 olikraus@gmail.com
* Bugfix for draw1x2string (u8x8 API)
* Changed return value for "begin()" (issue 518)
* New feature: U8log, https://github.com/olikraus/u8g2/wiki/u8logreference
* Added SSD1306 128x64 Adafruit OLED (issue 521)
* Added Winstart SSD1306 64x48 OLED variant (issue 522)
* Added support for JLX240160 (issue 556)
* Added support for JLX12864 (ST7565 variant, issue 440)
* Added support for JLX256160 (issue 561)
* Added support for SH1122 256x64 OLED (issue 420)
* Added open iconic icons (issue 535)
* Added several Persian fonts (issue 541)
* Added additional Japanese font variants (issue 581)
* Added Devanagari/Hindi font variant (issue 584)
* Added tom-thumb font (issue 563)
* Added AVR specific optimization for 3-wire Software SPI (issue 586)
2018-08-24 v2.23.18 olikraus@gmail.com
* NEW FONT FORMAT for speedup of the unicode font section (issue 596)
* Fixed a bug in the font construction for monospaced fonts (issue 669)
* Fixed a bug with the CS line for huge KS0108 displays (issue 631)
* Fixed #if's for some AVR uC (issue 662)
* Added support for SH1108 controller (issue 619)
* Added support for T6963 160x80 Displays (issue 635)
* Added support for EA W128128 (issue 641)
* Added support for LC7981 240x64 (issue 642)
* Added support for ST7567 ENH-DG128064 (issue 616)
* Included pull request for ST7586, support for ERC240160 & s028hn118a (pull request 660)
* Added SpaceTrash game (issue 622)
* Added contributed 7-segment font, https://github.com/olikraus/u8g2/wiki/fntgrpu8g#7segments_26x42 (issue 634)
* Added several fonts from fontstruct.com, https://github.com/olikraus/u8g2/wiki/fntgrpfontstruct (issue 687)#
This also includes several outline fonts.
2018-10-28 v2.24.3 olikraus@gmail.com
* Added clip window support (issue 364)
* Added setBusClock() proc to change the I2C/SPI bus clock speed (Arduino only, issue 705)
* Added sleep mode for ST7920 (issue 245)
* Added support for SSD0323 (issue 720)
2018-xx-xx v2.25.x olikraus@gmail.com
* Improved speed for I2C with SSD1306 controller: 4% faster now (issue 735)
* Fixed code problems (issues 766 and 754)
* Added battery and emoticons (issue 747)
* New U8x8 font format, added large U8x8 fonts (issue 771)

82
components/u8g2/LICENSE Normal file
View File

@ -0,0 +1,82 @@
The U8g2lib code (http://code.google.com/p/u8g2/) is licensed under the terms of
the new-bsd license (two-clause bsd license).
See also: http://www.opensource.org/licenses/bsd-license.php
The repository and optionally the releases contain icons, which are
derived from the WPZOOM Developer Icon Set:
http://www.wpzoom.com/wpzoom/new-freebie-wpzoom-developer-icon-set-154-free-icons/
WPZOOM Developer Icon Set by WPZOOM is licensed under a Creative Commons
Attribution-ShareAlike 3.0 Unported License.
Fonts are licensed under different conditions.
See
https://github.com/olikraus/u8g2/wiki/fntgrp
for detailed information on the licensing conditions for each font.
============ X11 Fonts COUR, HELV, NCEN, TIM, SYMB ============
For fonts derived from the following files, the license below applies.
COURB08.BDF COURB10.BDF COURB12.BDF COURB14.BDF COURB18.BDF
COURB24.BDF COURR08.BDF COURR10.BDF COURR12.BDF COURR14.BDF
COURR18.BDF COURR24.BDF HELVB08.BDF HELVB10.BDF HELVB12.BDF HELVB14.BDF
HELVB18.BDF HELVB24.BDF HELVR08.BDF HELVR10.BDF HELVR12.BDF HELVR14.BDF
HELVR18.BDF HELVR24.BDF NCENB08.BDF NCENB10.BDF NCENB12.BDF
NCENB14.BDF NCENB18.BDF NCENB24.BDF NCENR08.BDF NCENR10.BDF
NCENR12.BDF NCENR14.BDF NCENR18.BDF NCENR24.BDF SYMB08.BDF SYMB10.BDF
SYMB12.BDF SYMB14.BDF SYMB18.BDF SYMB24.BDF TIMB08.BDF TIMB10.BDF
TIMB12.BDF TIMB14.BDF TIMB18.BDF TIMB24.BDF TIMR08.BDF TIMR10.BDF
TIMR12.BDF TIMR14.BDF TIMR18.BDF TIMR24.BDF
Copyright 1984-1989, 1994 Adobe Systems Incorporated.
Copyright 1988, 1994 Digital Equipment Corporation.
Adobe is a trademark of Adobe Systems Incorporated which may be
registered in certain jurisdictions.
Permission to use these trademarks is hereby granted only in
association with the images described in this file.
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notices appear in all
copies and that both those copyright notices and this permission
notice appear in supporting documentation, and that the names of
Adobe Systems and Digital Equipment Corporation not be used in
advertising or publicity pertaining to distribution of the software
without specific, written prior permission. Adobe Systems and
Digital Equipment Corporation make no representations about the
suitability of this software for any purpose. It is provided "as
is" without express or implied warranty.
============ BSD License for U8g2lib Code ============
Universal 8bit Graphics Library (http://code.google.com/p/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

23
components/u8g2/README.md Normal file
View File

@ -0,0 +1,23 @@
![https://raw.githubusercontent.com/wiki/olikraus/u8g2/ref/u8g2_logo_transparent_orange.png](https://raw.githubusercontent.com/wiki/olikraus/u8g2/ref/u8g2_logo_transparent_orange.png)
U8g2: Library for monochrome displays, version 2
U8g2 is a monochrome graphics library for embedded devices.
U8g2 supports monochrome OLEDs and LCDs, which include the following controllers:
SSD1305, SSD1306, SSD1309, SSD1322, SSD1325, SSD1327, SSD1329, SSD1606, SSD1607,
SH1106, SH1107, SH1108, SH1122, T6963, RA8835, LC7981, PCD8544, PCF8812, HX1230,
UC1601, UC1604, UC1608, UC1610, UC1611, UC1701, ST7565, ST7567, ST7588, ST75256, NT7534, IST3020, ST7920, LD7032, KS0108, SED1520, SBN1661, IL3820, MAX7219
(see [here](https://github.com/olikraus/u8g2/wiki/u8g2setupcpp) for a full list).
The Arduino library U8g2 can be installed from the library manager of the Arduino IDE. U8g2 also includes U8x8 library:
* U8g2
* Includes all graphics procedures (line/box/circle draw).
* Supports many fonts. (Almost) no restriction on the font height.
* Requires some memory in the microcontroller to render the display.
* U8x8
* Text output only (character) device.
* Only fonts allowed with fit into a 8x8 pixel grid.
* Writes directly to the display. No buffer in the microcontroller required.
[Setup Guide and Reference Manual](https://github.com/olikraus/u8g2/wiki)

View File

@ -0,0 +1,2 @@
COMPONENT_SRCDIRS:=csrc
COMPONENT_ADD_INCLUDEDIRS:=csrc

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2703
components/u8g2/csrc/u8g2.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,218 @@
/*
u8g2_bitmap.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
void u8g2_SetBitmapMode(u8g2_t *u8g2, uint8_t is_transparent) {
u8g2->bitmap_transparency = is_transparent;
}
/*
x,y Position on the display
len Length of bitmap line in pixel. Note: This differs from u8glib which had a bytecount here.
b Pointer to the bitmap line.
Only draw pixels which are set.
*/
void u8g2_DrawHorizontalBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b)
{
uint8_t mask;
uint8_t color = u8g2->draw_color;
uint8_t ncolor = (color == 0 ? 1 : 0);
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
mask = 128;
while(len > 0)
{
if ( *b & mask ) {
u8g2->draw_color = color;
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
} else if ( u8g2->bitmap_transparency == 0 ) {
u8g2->draw_color = ncolor;
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
}
x++;
mask >>= 1;
if ( mask == 0 )
{
mask = 128;
b++;
}
len--;
}
u8g2->draw_color = color;
}
/* u8glib compatible bitmap draw function */
void u8g2_DrawBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t cnt, u8g2_uint_t h, const uint8_t *bitmap)
{
u8g2_uint_t w;
w = cnt;
w *= 8;
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
while( h > 0 )
{
u8g2_DrawHorizontalBitmap(u8g2, x, y, w, bitmap);
bitmap += cnt;
y++;
h--;
}
}
void u8g2_DrawHXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b)
{
uint8_t mask;
uint8_t color = u8g2->draw_color;
uint8_t ncolor = (color == 0 ? 1 : 0);
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
mask = 1;
while(len > 0) {
if ( *b & mask ) {
u8g2->draw_color = color;
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
} else if ( u8g2->bitmap_transparency == 0 ) {
u8g2->draw_color = ncolor;
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
}
x++;
mask <<= 1;
if ( mask == 0 )
{
mask = 1;
b++;
}
len--;
}
u8g2->draw_color = color;
}
void u8g2_DrawXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap)
{
u8g2_uint_t blen;
blen = w;
blen += 7;
blen >>= 3;
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
while( h > 0 )
{
u8g2_DrawHXBM(u8g2, x, y, w, bitmap);
bitmap += blen;
y++;
h--;
}
}
void u8g2_DrawHXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b)
{
uint8_t mask;
uint8_t color = u8g2->draw_color;
uint8_t ncolor = (color == 0 ? 1 : 0);
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
mask = 1;
while(len > 0)
{
if( u8x8_pgm_read(b) & mask ) {
u8g2->draw_color = color;
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
} else if( u8g2->bitmap_transparency == 0 ) {
u8g2->draw_color = ncolor;
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
}
x++;
mask <<= 1;
if ( mask == 0 )
{
mask = 1;
b++;
}
len--;
}
u8g2->draw_color = color;
}
void u8g2_DrawXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap)
{
u8g2_uint_t blen;
blen = w;
blen += 7;
blen >>= 3;
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
while( h > 0 )
{
u8g2_DrawHXBMP(u8g2, x, y, w, bitmap);
bitmap += blen;
y++;
h--;
}
}

View File

@ -0,0 +1,207 @@
/*
u8g2_box.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
/*
draw a filled box
restriction: does not work for w = 0 or h = 0
*/
void u8g2_DrawBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
while( h != 0 )
{
u8g2_DrawHVLine(u8g2, x, y, w, 0);
y++;
h--;
}
}
/*
draw a frame (empty box)
restriction: does not work for w = 0 or h = 0
ToDo:
pixel in the corners are drawn twice. This could be optimized.
*/
void u8g2_DrawFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h)
{
u8g2_uint_t xtmp = x;
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
u8g2_DrawHVLine(u8g2, x, y, w, 0);
u8g2_DrawHVLine(u8g2, x, y, h, 1);
x+=w;
x--;
u8g2_DrawHVLine(u8g2, x, y, h, 1);
y+=h;
y--;
u8g2_DrawHVLine(u8g2, xtmp, y, w, 0);
}
void u8g2_DrawRBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)
{
u8g2_uint_t xl, yu;
u8g2_uint_t yl, xr;
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
xl = x;
xl += r;
yu = y;
yu += r;
xr = x;
xr += w;
xr -= r;
xr -= 1;
yl = y;
yl += h;
yl -= r;
yl -= 1;
u8g2_DrawDisc(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT);
u8g2_DrawDisc(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT);
u8g2_DrawDisc(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT);
u8g2_DrawDisc(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT);
{
u8g2_uint_t ww, hh;
ww = w;
ww -= r;
ww -= r;
xl++;
yu++;
if ( ww >= 3 )
{
ww -= 2;
u8g2_DrawBox(u8g2, xl, y, ww, r+1);
u8g2_DrawBox(u8g2, xl, yl, ww, r+1);
}
hh = h;
hh -= r;
hh -= r;
//h--;
if ( hh >= 3 )
{
hh -= 2;
u8g2_DrawBox(u8g2, x, yu, w, hh);
}
}
}
void u8g2_DrawRFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)
{
u8g2_uint_t xl, yu;
#ifdef U8G2_WITH_INTERSECTION
if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 )
return;
#endif /* U8G2_WITH_INTERSECTION */
xl = x;
xl += r;
yu = y;
yu += r;
{
u8g2_uint_t yl, xr;
xr = x;
xr += w;
xr -= r;
xr -= 1;
yl = y;
yl += h;
yl -= r;
yl -= 1;
u8g2_DrawCircle(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT);
u8g2_DrawCircle(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT);
u8g2_DrawCircle(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT);
u8g2_DrawCircle(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT);
}
{
u8g2_uint_t ww, hh;
ww = w;
ww -= r;
ww -= r;
hh = h;
hh -= r;
hh -= r;
xl++;
yu++;
if ( ww >= 3 )
{
ww -= 2;
h--;
u8g2_DrawHLine(u8g2, xl, y, ww);
u8g2_DrawHLine(u8g2, xl, y+h, ww);
}
if ( hh >= 3 )
{
hh -= 2;
w--;
u8g2_DrawVLine(u8g2, x, yu, hh);
u8g2_DrawVLine(u8g2, x+w, yu, hh);
}
}
}

View File

@ -0,0 +1,176 @@
/*
u8g2_buffer.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
#include <string.h>
/*============================================*/
void u8g2_ClearBuffer(u8g2_t *u8g2)
{
size_t cnt;
cnt = u8g2_GetU8x8(u8g2)->display_info->tile_width;
cnt *= u8g2->tile_buf_height;
cnt *= 8;
memset(u8g2->tile_buf_ptr, 0, cnt);
}
/*============================================*/
static void u8g2_send_tile_row(u8g2_t *u8g2, uint8_t src_tile_row, uint8_t dest_tile_row)
{
uint8_t *ptr;
uint16_t offset;
uint8_t w;
w = u8g2_GetU8x8(u8g2)->display_info->tile_width;
offset = src_tile_row;
ptr = u8g2->tile_buf_ptr;
offset *= w;
offset *= 8;
ptr += offset;
u8x8_DrawTile(u8g2_GetU8x8(u8g2), 0, dest_tile_row, w, ptr);
}
/*
write the buffer to the display RAM.
For most displays, this will make the content visible to the user.
Some displays (like the SSD1606) require a u8x8_RefreshDisplay()
*/
static void u8g2_send_buffer(u8g2_t *u8g2) U8X8_NOINLINE;
static void u8g2_send_buffer(u8g2_t *u8g2)
{
uint8_t src_row;
uint8_t src_max;
uint8_t dest_row;
uint8_t dest_max;
src_row = 0;
src_max = u8g2->tile_buf_height;
dest_row = u8g2->tile_curr_row;
dest_max = u8g2_GetU8x8(u8g2)->display_info->tile_height;
do
{
u8g2_send_tile_row(u8g2, src_row, dest_row);
src_row++;
dest_row++;
} while( src_row < src_max && dest_row < dest_max );
}
/* same as u8g2_send_buffer but also send the DISPLAY_REFRESH message (used by SSD1606) */
void u8g2_SendBuffer(u8g2_t *u8g2)
{
u8g2_send_buffer(u8g2);
u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) );
}
/*============================================*/
void u8g2_SetBufferCurrTileRow(u8g2_t *u8g2, uint8_t row)
{
u8g2->tile_curr_row = row;
u8g2->cb->update_dimension(u8g2);
u8g2->cb->update_page_win(u8g2);
}
void u8g2_FirstPage(u8g2_t *u8g2)
{
if ( u8g2->is_auto_page_clear )
{
u8g2_ClearBuffer(u8g2);
}
u8g2_SetBufferCurrTileRow(u8g2, 0);
}
uint8_t u8g2_NextPage(u8g2_t *u8g2)
{
uint8_t row;
u8g2_send_buffer(u8g2);
row = u8g2->tile_curr_row;
row += u8g2->tile_buf_height;
if ( row >= u8g2_GetU8x8(u8g2)->display_info->tile_height )
{
u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) );
return 0;
}
if ( u8g2->is_auto_page_clear )
{
u8g2_ClearBuffer(u8g2);
}
u8g2_SetBufferCurrTileRow(u8g2, row);
return 1;
}
/*============================================*/
/*
Description:
Update a sub area of the display, given by tile position, width and height.
The arguments are "tile" coordinates. Any u8g2 rotation is ignored.
This procedure only checks whether full buffer mode is active.
There is no error checking for the arguments: It is the responsibility of the
user to ensure, that the provided arguments are correct.
Limitations:
- Only available in full buffer mode
- Tile positions and sizes (pixel position divided by 8)
- Any display rotation/mirror is ignored
- Only works with displays, which support U8x8 API
- Will not send the e-paper refresh message (will probably not work with e-paper devices)
*/
void u8g2_UpdateDisplayArea(u8g2_t *u8g2, uint8_t tx, uint8_t ty, uint8_t tw, uint8_t th)
{
uint16_t page_size;
uint8_t *ptr;
/* check, whether we are in full buffer mode */
if ( u8g2->tile_buf_height != u8g2_GetU8x8(u8g2)->display_info->tile_height )
return; /* not in full buffer mode, do nothing */
page_size = u8g2->pixel_buf_width; /* 8*u8g2->u8g2_GetU8x8(u8g2)->display_info->tile_width */
ptr = u8g2_GetBufferPtr(u8g2);
ptr += tx*8;
ptr += page_size*ty;
while( th > 0 )
{
u8x8_DrawTile( u8g2_GetU8x8(u8g2), tx, ty, tw, ptr );
ptr += page_size;
ty++;
th--;
}
}

View File

@ -0,0 +1,479 @@
/*
u8g2_box.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
/*==============================================*/
/* Circle */
static void u8g2_draw_circle_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
static void u8g2_draw_circle_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
{
/* upper right */
if ( option & U8G2_DRAW_UPPER_RIGHT )
{
u8g2_DrawPixel(u8g2, x0 + x, y0 - y);
u8g2_DrawPixel(u8g2, x0 + y, y0 - x);
}
/* upper left */
if ( option & U8G2_DRAW_UPPER_LEFT )
{
u8g2_DrawPixel(u8g2, x0 - x, y0 - y);
u8g2_DrawPixel(u8g2, x0 - y, y0 - x);
}
/* lower right */
if ( option & U8G2_DRAW_LOWER_RIGHT )
{
u8g2_DrawPixel(u8g2, x0 + x, y0 + y);
u8g2_DrawPixel(u8g2, x0 + y, y0 + x);
}
/* lower left */
if ( option & U8G2_DRAW_LOWER_LEFT )
{
u8g2_DrawPixel(u8g2, x0 - x, y0 + y);
u8g2_DrawPixel(u8g2, x0 - y, y0 + x);
}
}
static void u8g2_draw_circle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
{
u8g2_int_t f;
u8g2_int_t ddF_x;
u8g2_int_t ddF_y;
u8g2_uint_t x;
u8g2_uint_t y;
f = 1;
f -= rad;
ddF_x = 1;
ddF_y = 0;
ddF_y -= rad;
ddF_y *= 2;
x = 0;
y = rad;
u8g2_draw_circle_section(u8g2, x, y, x0, y0, option);
while ( x < y )
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
u8g2_draw_circle_section(u8g2, x, y, x0, y0, option);
}
}
void u8g2_DrawCircle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
{
/* check for bounding box */
#ifdef U8G2_WITH_INTERSECTION
{
if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )
return;
}
#endif /* U8G2_WITH_INTERSECTION */
/* draw circle */
u8g2_draw_circle(u8g2, x0, y0, rad, option);
}
/*==============================================*/
/* Disk */
static void u8g2_draw_disc_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
static void u8g2_draw_disc_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
{
/* upper right */
if ( option & U8G2_DRAW_UPPER_RIGHT )
{
u8g2_DrawVLine(u8g2, x0+x, y0-y, y+1);
u8g2_DrawVLine(u8g2, x0+y, y0-x, x+1);
}
/* upper left */
if ( option & U8G2_DRAW_UPPER_LEFT )
{
u8g2_DrawVLine(u8g2, x0-x, y0-y, y+1);
u8g2_DrawVLine(u8g2, x0-y, y0-x, x+1);
}
/* lower right */
if ( option & U8G2_DRAW_LOWER_RIGHT )
{
u8g2_DrawVLine(u8g2, x0+x, y0, y+1);
u8g2_DrawVLine(u8g2, x0+y, y0, x+1);
}
/* lower left */
if ( option & U8G2_DRAW_LOWER_LEFT )
{
u8g2_DrawVLine(u8g2, x0-x, y0, y+1);
u8g2_DrawVLine(u8g2, x0-y, y0, x+1);
}
}
static void u8g2_draw_disc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
{
u8g2_int_t f;
u8g2_int_t ddF_x;
u8g2_int_t ddF_y;
u8g2_uint_t x;
u8g2_uint_t y;
f = 1;
f -= rad;
ddF_x = 1;
ddF_y = 0;
ddF_y -= rad;
ddF_y *= 2;
x = 0;
y = rad;
u8g2_draw_disc_section(u8g2, x, y, x0, y0, option);
while ( x < y )
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
u8g2_draw_disc_section(u8g2, x, y, x0, y0, option);
}
}
void u8g2_DrawDisc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
{
/* check for bounding box */
#ifdef U8G2_WITH_INTERSECTION
{
if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )
return;
}
#endif /* U8G2_WITH_INTERSECTION */
/* draw disc */
u8g2_draw_disc(u8g2, x0, y0, rad, option);
}
/*==============================================*/
/* Ellipse */
/*
Source:
Foley, Computer Graphics, p 90
*/
static void u8g2_draw_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
static void u8g2_draw_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
{
/* upper right */
if ( option & U8G2_DRAW_UPPER_RIGHT )
{
u8g2_DrawPixel(u8g2, x0 + x, y0 - y);
}
/* upper left */
if ( option & U8G2_DRAW_UPPER_LEFT )
{
u8g2_DrawPixel(u8g2, x0 - x, y0 - y);
}
/* lower right */
if ( option & U8G2_DRAW_LOWER_RIGHT )
{
u8g2_DrawPixel(u8g2, x0 + x, y0 + y);
}
/* lower left */
if ( option & U8G2_DRAW_LOWER_LEFT )
{
u8g2_DrawPixel(u8g2, x0 - x, y0 + y);
}
}
static void u8g2_draw_ellipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
{
u8g2_uint_t x, y;
u8g2_long_t xchg, ychg;
u8g2_long_t err;
u8g2_long_t rxrx2;
u8g2_long_t ryry2;
u8g2_long_t stopx, stopy;
rxrx2 = rx;
rxrx2 *= rx;
rxrx2 *= 2;
ryry2 = ry;
ryry2 *= ry;
ryry2 *= 2;
x = rx;
y = 0;
xchg = 1;
xchg -= rx;
xchg -= rx;
xchg *= ry;
xchg *= ry;
ychg = rx;
ychg *= rx;
err = 0;
stopx = ryry2;
stopx *= rx;
stopy = 0;
while( stopx >= stopy )
{
u8g2_draw_ellipse_section(u8g2, x, y, x0, y0, option);
y++;
stopy += rxrx2;
err += ychg;
ychg += rxrx2;
if ( 2*err+xchg > 0 )
{
x--;
stopx -= ryry2;
err += xchg;
xchg += ryry2;
}
}
x = 0;
y = ry;
xchg = ry;
xchg *= ry;
ychg = 1;
ychg -= ry;
ychg -= ry;
ychg *= rx;
ychg *= rx;
err = 0;
stopx = 0;
stopy = rxrx2;
stopy *= ry;
while( stopx <= stopy )
{
u8g2_draw_ellipse_section(u8g2, x, y, x0, y0, option);
x++;
stopx += ryry2;
err += xchg;
xchg += ryry2;
if ( 2*err+ychg > 0 )
{
y--;
stopy -= rxrx2;
err += ychg;
ychg += rxrx2;
}
}
}
void u8g2_DrawEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
{
/* check for bounding box */
#ifdef U8G2_WITH_INTERSECTION
{
if ( u8g2_IsIntersection(u8g2, x0-rx, y0-ry, x0+rx+1, y0+ry+1) == 0 )
return;
}
#endif /* U8G2_WITH_INTERSECTION */
u8g2_draw_ellipse(u8g2, x0, y0, rx, ry, option);
}
/*==============================================*/
/* Filled Ellipse */
static void u8g2_draw_filled_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
static void u8g2_draw_filled_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
{
/* upper right */
if ( option & U8G2_DRAW_UPPER_RIGHT )
{
u8g2_DrawVLine(u8g2, x0+x, y0-y, y+1);
}
/* upper left */
if ( option & U8G2_DRAW_UPPER_LEFT )
{
u8g2_DrawVLine(u8g2, x0-x, y0-y, y+1);
}
/* lower right */
if ( option & U8G2_DRAW_LOWER_RIGHT )
{
u8g2_DrawVLine(u8g2, x0+x, y0, y+1);
}
/* lower left */
if ( option & U8G2_DRAW_LOWER_LEFT )
{
u8g2_DrawVLine(u8g2, x0-x, y0, y+1);
}
}
static void u8g2_draw_filled_ellipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
{
u8g2_uint_t x, y;
u8g2_long_t xchg, ychg;
u8g2_long_t err;
u8g2_long_t rxrx2;
u8g2_long_t ryry2;
u8g2_long_t stopx, stopy;
rxrx2 = rx;
rxrx2 *= rx;
rxrx2 *= 2;
ryry2 = ry;
ryry2 *= ry;
ryry2 *= 2;
x = rx;
y = 0;
xchg = 1;
xchg -= rx;
xchg -= rx;
xchg *= ry;
xchg *= ry;
ychg = rx;
ychg *= rx;
err = 0;
stopx = ryry2;
stopx *= rx;
stopy = 0;
while( stopx >= stopy )
{
u8g2_draw_filled_ellipse_section(u8g2, x, y, x0, y0, option);
y++;
stopy += rxrx2;
err += ychg;
ychg += rxrx2;
if ( 2*err+xchg > 0 )
{
x--;
stopx -= ryry2;
err += xchg;
xchg += ryry2;
}
}
x = 0;
y = ry;
xchg = ry;
xchg *= ry;
ychg = 1;
ychg -= ry;
ychg -= ry;
ychg *= rx;
ychg *= rx;
err = 0;
stopx = 0;
stopy = rxrx2;
stopy *= ry;
while( stopx <= stopy )
{
u8g2_draw_filled_ellipse_section(u8g2, x, y, x0, y0, option);
x++;
stopx += ryry2;
err += xchg;
xchg += ryry2;
if ( 2*err+ychg > 0 )
{
y--;
stopy -= rxrx2;
err += ychg;
ychg += rxrx2;
}
}
}
void u8g2_DrawFilledEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
{
/* check for bounding box */
#ifdef U8G2_WITH_INTERSECTION
{
if ( u8g2_IsIntersection(u8g2, x0-rx, y0-ry, x0+rx+1, y0+ry+1) == 0 )
return;
}
#endif /* U8G2_WITH_INTERSECTION */
u8g2_draw_filled_ellipse(u8g2, x0, y0, rx, ry, option);
}

View File

@ -0,0 +1,54 @@
/*
u8g2_cleardisplay.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
/* Clear screen buffer & display reliable for all u8g2 displays. */
/* This is done with u8g2 picture loop, because we can not use the u8x8 function in all cases */
void u8g2_ClearDisplay(u8g2_t *u8g2)
{
u8g2_FirstPage(u8g2);
do {
} while ( u8g2_NextPage(u8g2) );
/*
This function is usually called during startup (u8g2.begin()).
However the user might want to use full buffer mode with clear and
send commands.
This will not work because the current tile row is modified by the picture
loop above. To fix this, reset the tile row to 0, issue #370
A workaround would be, that the user sets the current tile row to 0 manually.
*/
u8g2_SetBufferCurrTileRow(u8g2, 0);
}

View File

@ -0,0 +1,762 @@
/* u8g2_d_memory.c */
/* generated code, codebuild, u8g2 project */
#include "u8g2.h"
uint8_t *u8g2_m_16_4_1(uint8_t *page_cnt)
{
static uint8_t buf[128];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_16_4_2(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_16_4_f(uint8_t *page_cnt)
{
static uint8_t buf[512];
*page_cnt = 4;
return buf;
}
uint8_t *u8g2_m_16_8_1(uint8_t *page_cnt)
{
static uint8_t buf[128];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_16_8_2(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_16_8_f(uint8_t *page_cnt)
{
static uint8_t buf[1024];
*page_cnt = 8;
return buf;
}
uint8_t *u8g2_m_9_5_1(uint8_t *page_cnt)
{
static uint8_t buf[72];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_9_5_2(uint8_t *page_cnt)
{
static uint8_t buf[144];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_9_5_f(uint8_t *page_cnt)
{
static uint8_t buf[360];
*page_cnt = 5;
return buf;
}
uint8_t *u8g2_m_8_4_1(uint8_t *page_cnt)
{
static uint8_t buf[64];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_8_4_2(uint8_t *page_cnt)
{
static uint8_t buf[128];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_8_4_f(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 4;
return buf;
}
uint8_t *u8g2_m_8_16_1(uint8_t *page_cnt)
{
static uint8_t buf[64];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_8_16_2(uint8_t *page_cnt)
{
static uint8_t buf[128];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_8_16_f(uint8_t *page_cnt)
{
static uint8_t buf[1024];
*page_cnt = 16;
return buf;
}
uint8_t *u8g2_m_12_12_1(uint8_t *page_cnt)
{
static uint8_t buf[96];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_12_12_2(uint8_t *page_cnt)
{
static uint8_t buf[192];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_12_12_f(uint8_t *page_cnt)
{
static uint8_t buf[1152];
*page_cnt = 12;
return buf;
}
uint8_t *u8g2_m_16_16_1(uint8_t *page_cnt)
{
static uint8_t buf[128];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_16_16_2(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_16_16_f(uint8_t *page_cnt)
{
static uint8_t buf[2048];
*page_cnt = 16;
return buf;
}
uint8_t *u8g2_m_20_20_1(uint8_t *page_cnt)
{
static uint8_t buf[160];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_20_20_2(uint8_t *page_cnt)
{
static uint8_t buf[320];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_20_20_f(uint8_t *page_cnt)
{
static uint8_t buf[3200];
*page_cnt = 20;
return buf;
}
uint8_t *u8g2_m_32_8_1(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_32_8_2(uint8_t *page_cnt)
{
static uint8_t buf[512];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_32_8_f(uint8_t *page_cnt)
{
static uint8_t buf[2048];
*page_cnt = 8;
return buf;
}
uint8_t *u8g2_m_8_6_1(uint8_t *page_cnt)
{
static uint8_t buf[64];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_8_6_2(uint8_t *page_cnt)
{
static uint8_t buf[128];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_8_6_f(uint8_t *page_cnt)
{
static uint8_t buf[384];
*page_cnt = 6;
return buf;
}
uint8_t *u8g2_m_6_8_1(uint8_t *page_cnt)
{
static uint8_t buf[48];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_6_8_2(uint8_t *page_cnt)
{
static uint8_t buf[96];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_6_8_f(uint8_t *page_cnt)
{
static uint8_t buf[384];
*page_cnt = 8;
return buf;
}
uint8_t *u8g2_m_12_2_1(uint8_t *page_cnt)
{
static uint8_t buf[96];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_12_2_2(uint8_t *page_cnt)
{
static uint8_t buf[192];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_12_2_f(uint8_t *page_cnt)
{
static uint8_t buf[192];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_32_4_1(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_32_4_2(uint8_t *page_cnt)
{
static uint8_t buf[512];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_32_4_f(uint8_t *page_cnt)
{
static uint8_t buf[1024];
*page_cnt = 4;
return buf;
}
uint8_t *u8g2_m_16_12_1(uint8_t *page_cnt)
{
static uint8_t buf[128];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_16_12_2(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_16_12_f(uint8_t *page_cnt)
{
static uint8_t buf[1536];
*page_cnt = 12;
return buf;
}
uint8_t *u8g2_m_24_4_1(uint8_t *page_cnt)
{
static uint8_t buf[192];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_24_4_2(uint8_t *page_cnt)
{
static uint8_t buf[384];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_24_4_f(uint8_t *page_cnt)
{
static uint8_t buf[768];
*page_cnt = 4;
return buf;
}
uint8_t *u8g2_m_50_30_1(uint8_t *page_cnt)
{
static uint8_t buf[400];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_50_30_2(uint8_t *page_cnt)
{
static uint8_t buf[800];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_50_30_f(uint8_t *page_cnt)
{
static uint8_t buf[12000];
*page_cnt = 30;
return buf;
}
uint8_t *u8g2_m_18_21_1(uint8_t *page_cnt)
{
static uint8_t buf[144];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_18_21_2(uint8_t *page_cnt)
{
static uint8_t buf[288];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_18_21_f(uint8_t *page_cnt)
{
static uint8_t buf[3024];
*page_cnt = 21;
return buf;
}
uint8_t *u8g2_m_13_8_1(uint8_t *page_cnt)
{
static uint8_t buf[104];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_13_8_2(uint8_t *page_cnt)
{
static uint8_t buf[208];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_13_8_f(uint8_t *page_cnt)
{
static uint8_t buf[832];
*page_cnt = 8;
return buf;
}
uint8_t *u8g2_m_11_6_1(uint8_t *page_cnt)
{
static uint8_t buf[88];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_11_6_2(uint8_t *page_cnt)
{
static uint8_t buf[176];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_11_6_f(uint8_t *page_cnt)
{
static uint8_t buf[528];
*page_cnt = 6;
return buf;
}
uint8_t *u8g2_m_12_9_1(uint8_t *page_cnt)
{
static uint8_t buf[96];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_12_9_2(uint8_t *page_cnt)
{
static uint8_t buf[192];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_12_9_f(uint8_t *page_cnt)
{
static uint8_t buf[864];
*page_cnt = 9;
return buf;
}
uint8_t *u8g2_m_24_8_1(uint8_t *page_cnt)
{
static uint8_t buf[192];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_24_8_2(uint8_t *page_cnt)
{
static uint8_t buf[384];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_24_8_f(uint8_t *page_cnt)
{
static uint8_t buf[1536];
*page_cnt = 8;
return buf;
}
uint8_t *u8g2_m_30_8_1(uint8_t *page_cnt)
{
static uint8_t buf[240];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_30_8_2(uint8_t *page_cnt)
{
static uint8_t buf[480];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_30_8_f(uint8_t *page_cnt)
{
static uint8_t buf[1920];
*page_cnt = 8;
return buf;
}
uint8_t *u8g2_m_30_15_1(uint8_t *page_cnt)
{
static uint8_t buf[240];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_30_15_2(uint8_t *page_cnt)
{
static uint8_t buf[480];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_30_15_f(uint8_t *page_cnt)
{
static uint8_t buf[3600];
*page_cnt = 15;
return buf;
}
uint8_t *u8g2_m_30_16_1(uint8_t *page_cnt)
{
static uint8_t buf[240];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_30_16_2(uint8_t *page_cnt)
{
static uint8_t buf[480];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_30_16_f(uint8_t *page_cnt)
{
static uint8_t buf[3840];
*page_cnt = 16;
return buf;
}
uint8_t *u8g2_m_20_16_1(uint8_t *page_cnt)
{
static uint8_t buf[160];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_20_16_2(uint8_t *page_cnt)
{
static uint8_t buf[320];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_20_16_f(uint8_t *page_cnt)
{
static uint8_t buf[2560];
*page_cnt = 16;
return buf;
}
uint8_t *u8g2_m_20_13_1(uint8_t *page_cnt)
{
static uint8_t buf[160];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_20_13_2(uint8_t *page_cnt)
{
static uint8_t buf[320];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_20_13_f(uint8_t *page_cnt)
{
static uint8_t buf[2080];
*page_cnt = 13;
return buf;
}
uint8_t *u8g2_m_30_20_1(uint8_t *page_cnt)
{
static uint8_t buf[240];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_30_20_2(uint8_t *page_cnt)
{
static uint8_t buf[480];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_30_20_f(uint8_t *page_cnt)
{
static uint8_t buf[4800];
*page_cnt = 20;
return buf;
}
uint8_t *u8g2_m_17_4_1(uint8_t *page_cnt)
{
static uint8_t buf[136];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_17_4_2(uint8_t *page_cnt)
{
static uint8_t buf[272];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_17_4_f(uint8_t *page_cnt)
{
static uint8_t buf[544];
*page_cnt = 4;
return buf;
}
uint8_t *u8g2_m_17_8_1(uint8_t *page_cnt)
{
static uint8_t buf[136];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_17_8_2(uint8_t *page_cnt)
{
static uint8_t buf[272];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_17_8_f(uint8_t *page_cnt)
{
static uint8_t buf[1088];
*page_cnt = 8;
return buf;
}
uint8_t *u8g2_m_48_17_1(uint8_t *page_cnt)
{
static uint8_t buf[384];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_48_17_2(uint8_t *page_cnt)
{
static uint8_t buf[768];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_48_17_f(uint8_t *page_cnt)
{
static uint8_t buf[6528];
*page_cnt = 17;
return buf;
}
uint8_t *u8g2_m_32_16_1(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_32_16_2(uint8_t *page_cnt)
{
static uint8_t buf[512];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_32_16_f(uint8_t *page_cnt)
{
static uint8_t buf[4096];
*page_cnt = 16;
return buf;
}
uint8_t *u8g2_m_32_20_1(uint8_t *page_cnt)
{
static uint8_t buf[256];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_32_20_2(uint8_t *page_cnt)
{
static uint8_t buf[512];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_32_20_f(uint8_t *page_cnt)
{
static uint8_t buf[5120];
*page_cnt = 20;
return buf;
}
uint8_t *u8g2_m_22_13_1(uint8_t *page_cnt)
{
static uint8_t buf[176];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_22_13_2(uint8_t *page_cnt)
{
static uint8_t buf[352];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_22_13_f(uint8_t *page_cnt)
{
static uint8_t buf[2288];
*page_cnt = 13;
return buf;
}
uint8_t *u8g2_m_20_10_1(uint8_t *page_cnt)
{
static uint8_t buf[160];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_20_10_2(uint8_t *page_cnt)
{
static uint8_t buf[320];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_20_10_f(uint8_t *page_cnt)
{
static uint8_t buf[1600];
*page_cnt = 10;
return buf;
}
uint8_t *u8g2_m_22_9_1(uint8_t *page_cnt)
{
static uint8_t buf[176];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_22_9_2(uint8_t *page_cnt)
{
static uint8_t buf[352];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_22_9_f(uint8_t *page_cnt)
{
static uint8_t buf[1584];
*page_cnt = 9;
return buf;
}
uint8_t *u8g2_m_25_25_1(uint8_t *page_cnt)
{
static uint8_t buf[200];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_25_25_2(uint8_t *page_cnt)
{
static uint8_t buf[400];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_25_25_f(uint8_t *page_cnt)
{
static uint8_t buf[5000];
*page_cnt = 25;
return buf;
}
uint8_t *u8g2_m_37_16_1(uint8_t *page_cnt)
{
static uint8_t buf[296];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_37_16_2(uint8_t *page_cnt)
{
static uint8_t buf[592];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_37_16_f(uint8_t *page_cnt)
{
static uint8_t buf[4736];
*page_cnt = 16;
return buf;
}
uint8_t *u8g2_m_40_30_1(uint8_t *page_cnt)
{
static uint8_t buf[320];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_40_30_2(uint8_t *page_cnt)
{
static uint8_t buf[640];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_40_30_f(uint8_t *page_cnt)
{
static uint8_t buf[9600];
*page_cnt = 30;
return buf;
}
uint8_t *u8g2_m_8_1_1(uint8_t *page_cnt)
{
static uint8_t buf[64];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_8_1_2(uint8_t *page_cnt)
{
static uint8_t buf[128];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_8_1_f(uint8_t *page_cnt)
{
static uint8_t buf[64];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_4_1_1(uint8_t *page_cnt)
{
static uint8_t buf[32];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_4_1_2(uint8_t *page_cnt)
{
static uint8_t buf[64];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_4_1_f(uint8_t *page_cnt)
{
static uint8_t buf[32];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_1_1_1(uint8_t *page_cnt)
{
static uint8_t buf[8];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_1_1_2(uint8_t *page_cnt)
{
static uint8_t buf[16];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_1_1_f(uint8_t *page_cnt)
{
static uint8_t buf[8];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_48_30_1(uint8_t *page_cnt)
{
static uint8_t buf[384];
*page_cnt = 1;
return buf;
}
uint8_t *u8g2_m_48_30_2(uint8_t *page_cnt)
{
static uint8_t buf[768];
*page_cnt = 2;
return buf;
}
uint8_t *u8g2_m_48_30_f(uint8_t *page_cnt)
{
static uint8_t buf[11520];
*page_cnt = 30;
return buf;
}
/* end of generated code */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,255 @@
/*
u8g2_hvline.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Calltree
void u8g2_DrawHVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
u8g2->cb->draw_l90
u8g2_draw_hv_line_2dir
u8g2->ll_hvline(u8g2, x, y, len, dir);
*/
#include "u8g2.h"
#include <assert.h>
/*==========================================================*/
/* intersection procedure */
/*
Description:
clip range from pos a (included) with line len (a+len excluded) agains c (included) to d (excluded)
Assumptions:
len > 0
c <= d (this is not checked)
will return 0 if there is no intersection and if a > b
*/
static uint8_t u8g2_clip_intersection2(u8g2_uint_t *ap, u8g2_uint_t *len, u8g2_uint_t c, u8g2_uint_t d)
{
u8g2_uint_t a = *ap;
u8g2_uint_t b;
b = a;
b += *len;
/*
Description:
clip range from a (included) to b (excluded) agains c (included) to d (excluded)
Assumptions:
a <= b (violation is checked and handled correctly)
c <= d (this is not checked)
will return 0 if there is no intersection and if a > b
optimized clipping: c is set to 0 --> 27 Oct 2018: again removed the c==0 assumption
replaced by uint8_t u8g2_clip_intersection2
*/
/* handle the a>b case correctly. If code and time is critical, this could */
/* be removed completly (be aware about memory curruption for wrong */
/* arguments) or return 0 for a>b (will lead to skipped lines for wrong */
/* arguments) */
/* removing the following if clause completly may lead to memory corruption of a>b */
if ( a > b )
{
/* replacing this if with a simple "return 0;" will not handle the case with negative a */
if ( a < d )
{
b = d;
b--;
}
else
{
a = c;
}
}
/* from now on, the asumption a <= b is ok */
if ( a >= d )
return 0;
if ( b <= c )
return 0;
if ( a < c )
a = c;
if ( b > d )
b = d;
*ap = a;
b -= a;
*len = b;
return 1;
}
/*==========================================================*/
/* draw procedures */
/*
x,y Upper left position of the line within the pixel buffer
len length of the line in pixel, len must not be 0
dir 0: horizontal line (left to right)
1: vertical line (top to bottom)
This function first adjusts the y position to the local buffer. Then it
will clip the line and call u8g2_draw_low_level_hv_line()
*/
void u8g2_draw_hv_line_2dir(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
/* clipping happens before the display rotation */
/* transform to pixel buffer coordinates */
y -= u8g2->pixel_curr_row;
u8g2->ll_hvline(u8g2, x, y, len, dir);
}
/*
This is the toplevel function for the hv line draw procedures.
This function should be called by the user.
"dir" may have 4 directions: 0 (left to right), 1, 2, 3 (down up)
*/
void u8g2_DrawHVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
/* Make a call to the callback function (e.g. u8g2_draw_l90_r0). */
/* The callback may rotate the hv line */
/* after rotation this will call u8g2_draw_hv_line_4dir() */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
if ( u8g2->is_page_clip_window_intersection != 0 )
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
if ( len != 0 )
{
/* convert to two directions */
if ( len > 1 )
{
if ( dir == 2 )
{
x -= len;
x++;
}
else if ( dir == 3 )
{
y -= len;
y++;
}
}
dir &= 1;
/* clip against the user window */
if ( dir == 0 )
{
if ( y < u8g2->user_y0 )
return;
if ( y >= u8g2->user_y1 )
return;
if ( u8g2_clip_intersection2(&x, &len, u8g2->user_x0, u8g2->user_x1) == 0 )
return;
}
else
{
if ( x < u8g2->user_x0 )
return;
if ( x >= u8g2->user_x1 )
return;
if ( u8g2_clip_intersection2(&y, &len, u8g2->user_y0, u8g2->user_y1) == 0 )
return;
}
u8g2->cb->draw_l90(u8g2, x, y, len, dir);
}
}
void u8g2_DrawHLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len)
{
// #ifdef U8G2_WITH_INTERSECTION
// if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 )
// return;
// #endif /* U8G2_WITH_INTERSECTION */
u8g2_DrawHVLine(u8g2, x, y, len, 0);
}
void u8g2_DrawVLine(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len)
{
// #ifdef U8G2_WITH_INTERSECTION
// if ( u8g2_IsIntersection(u8g2, x, y, x+1, y+len) == 0 )
// return;
// #endif /* U8G2_WITH_INTERSECTION */
u8g2_DrawHVLine(u8g2, x, y, len, 1);
}
void u8g2_DrawPixel(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y)
{
#ifdef U8G2_WITH_INTERSECTION
if ( y < u8g2->user_y0 )
return;
if ( y >= u8g2->user_y1 )
return;
if ( x < u8g2->user_x0 )
return;
if ( x >= u8g2->user_x1 )
return;
#endif /* U8G2_WITH_INTERSECTION */
u8g2_DrawHVLine(u8g2, x, y, 1, 0);
}
/*
Assign the draw color for all drawing functions.
color may be 0 or 1. The actual color is defined by the display.
With color = 1 the drawing function will set the display memory to 1.
For OLEDs this ususally means, that the pixel is enabled and the LED
at the pixel is turned on.
On an LCD it usually means that the LCD segment of the pixel is enabled,
which absorbs the light.
For eInk/ePaper it means black ink.
7 Jan 2017: Allow color value 2 for XOR operation.
*/
void u8g2_SetDrawColor(u8g2_t *u8g2, uint8_t color)
{
u8g2->draw_color = color; /* u8g2_SetDrawColor: just assign the argument */
if ( color >= 3 )
u8g2->draw_color = 1; /* u8g2_SetDrawColor: make color as one if arg is invalid */
}

View File

@ -0,0 +1,150 @@
/*
u8g2_input_value.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
/*
return:
0: value is not changed (HOME/Break Button pressed)
1: value has been updated
*/
uint8_t u8g2_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post)
{
uint8_t line_height;
uint8_t height;
u8g2_uint_t pixel_height;
u8g2_uint_t y, yy;
u8g2_uint_t pixel_width;
u8g2_uint_t x, xx;
uint8_t local_value = *value;
//uint8_t r; /* not used ??? */
uint8_t event;
/* only horizontal strings are supported, so force this here */
u8g2_SetFontDirection(u8g2, 0);
/* force baseline position */
u8g2_SetFontPosBaseline(u8g2);
/* calculate line height */
line_height = u8g2_GetAscent(u8g2);
line_height -= u8g2_GetDescent(u8g2);
/* calculate overall height of the input value box */
height = 1; /* value input line */
height += u8x8_GetStringLineCnt(title);
/* calculate the height in pixel */
pixel_height = height;
pixel_height *= line_height;
/* calculate offset from top */
y = 0;
if ( pixel_height < u8g2_GetDisplayHeight(u8g2) )
{
y = u8g2_GetDisplayHeight(u8g2);
y -= pixel_height;
y /= 2;
}
/* calculate offset from left for the label */
x = 0;
pixel_width = u8g2_GetUTF8Width(u8g2, pre);
pixel_width += u8g2_GetUTF8Width(u8g2, "0") * digits;
pixel_width += u8g2_GetUTF8Width(u8g2, post);
if ( pixel_width < u8g2_GetDisplayWidth(u8g2) )
{
x = u8g2_GetDisplayWidth(u8g2);
x -= pixel_width;
x /= 2;
}
/* event loop */
for(;;)
{
u8g2_FirstPage(u8g2);
do
{
/* render */
yy = y;
yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title);
xx = x;
xx += u8g2_DrawUTF8(u8g2, xx, yy, pre);
xx += u8g2_DrawUTF8(u8g2, xx, yy, u8x8_u8toa(local_value, digits));
u8g2_DrawUTF8(u8g2, xx, yy, post);
} while( u8g2_NextPage(u8g2) );
#ifdef U8G2_REF_MAN_PIC
return 0;
#endif
for(;;)
{
event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2));
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
{
*value = local_value;
return 1;
}
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
{
return 0;
}
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP )
{
if ( local_value >= hi )
local_value = lo;
else
local_value++;
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN )
{
if ( local_value <= lo )
local_value = hi;
else
local_value--;
break;
}
}
}
/* never reached */
//return r;
}

View File

@ -0,0 +1,176 @@
/*
u8g2_intersection.c
Intersection calculation, code taken from u8g_clip.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
#ifdef __GNUC__
#define U8G2_ALWAYS_INLINE __inline__ __attribute__((always_inline))
#else
#define U8G2_ALWAYS_INLINE
#endif
#if defined(U8G2_WITH_INTERSECTION) || defined(U8G2_WITH_CLIP_WINDOW_SUPPORT)
#ifdef OLD_VERSION_WITH_SYMETRIC_BOUNDARIES
/*
intersection assumptions:
a1 <= a2 is always true
minimized version
---1----0 1 b1 <= a2 && b1 > b2
-----1--0 1 b2 >= a1 && b1 > b2
---1-1--- 1 b1 <= a2 && b2 >= a1
*/
/*
calculate the intersection between a0/a1 and v0/v1
The intersection check returns one if the range of a0/a1 has an intersection with v0/v1.
The intersection check includes the boundary values v1 and a1.
The following asserts will succeed:
assert( u8g2_is_intersection_decision_tree(4, 6, 7, 9) == 0 );
assert( u8g2_is_intersection_decision_tree(4, 6, 6, 9) != 0 );
assert( u8g2_is_intersection_decision_tree(6, 9, 4, 6) != 0 );
assert( u8g2_is_intersection_decision_tree(7, 9, 4, 6) == 0 );
*/
//static uint8_t U8G2_ALWAYS_INLINE u8g2_is_intersection_decision_tree(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1)
static uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1)
{
if ( v0 <= a1 )
{
if ( v1 >= a0 )
{
return 1;
}
else
{
if ( v0 > v1 )
{
return 1;
}
else
{
return 0;
}
}
}
else
{
if ( v1 >= a0 )
{
if ( v0 > v1 )
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
}
#endif /* OLD_VERSION_WITH_SYMETRIC_BOUNDARIES */
/*
version with asymetric boundaries.
a1 and v1 are excluded
v0 == v1 is not support end return 1
*/
uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1)
{
if ( v0 < a1 ) // v0 <= a1
{
if ( v1 > a0 ) // v1 >= a0
{
return 1;
}
else
{
if ( v0 > v1 ) // v0 > v1
{
return 1;
}
else
{
return 0;
}
}
}
else
{
if ( v1 > a0 ) // v1 >= a0
{
if ( v0 > v1 ) // v0 > v1
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0;
}
}
}
/* upper limits are not included (asymetric boundaries) */
uint8_t u8g2_IsIntersection(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1)
{
if ( u8g2_is_intersection_decision_tree(u8g2->user_y0, u8g2->user_y1, y0, y1) == 0 )
return 0;
return u8g2_is_intersection_decision_tree(u8g2->user_x0, u8g2->user_x1, x0, x1);
}
#endif /* U8G2_WITH_INTERSECTION */

View File

@ -0,0 +1,94 @@
/*
u8g2_kerning.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
/* this function is used as "u8g2_get_kerning_cb" */
/*
uint8_t u8g2_GetNullKerning(u8g2_t *u8g2, uint16_t e1, uint16_t e2)
{
return 0;
}
*/
/* this function is used as "u8g2_get_kerning_cb" */
uint8_t u8g2_GetKerning(U8X8_UNUSED u8g2_t *u8g2, u8g2_kerning_t *kerning, uint16_t e1, uint16_t e2)
{
uint16_t i1, i2, cnt, end;
if ( kerning == NULL )
return 0;
/* search for the encoding in the first table */
cnt = kerning->first_table_cnt;
cnt--; /* ignore the last element of the table, which is 0x0ffff */
for( i1 = 0; i1 < cnt; i1++ )
{
if ( kerning->first_encoding_table[i1] == e1 )
break;
}
if ( i1 >= cnt )
return 0; /* e1 not part of the kerning table, return 0 */
/* get the upper index for i2 */
end = kerning->index_to_second_table[i1+1];
for( i2 = kerning->index_to_second_table[i1]; i2 < end; i2++ )
{
if ( kerning->second_encoding_table[i2] == e2 )
break;
}
if ( i2 >= end )
return 0; /* e2 not part of any pair with e1, return 0 */
return kerning->kerning_values[i2];
}
uint8_t u8g2_GetKerningByTable(U8X8_UNUSED u8g2_t *u8g2, const uint16_t *kt, uint16_t e1, uint16_t e2)
{
uint16_t i;
i = 0;
if ( kt == NULL )
return 0;
for(;;)
{
if ( kt[i] == 0x0ffff )
break;
if ( kt[i] == e1 && kt[i+1] == e2 )
return kt[i+2];
i+=3;
}
return 0;
}

View File

@ -0,0 +1,92 @@
/*
u8g2_box.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
void u8g2_DrawLine(u8g2_t *u8g2, u8g2_uint_t x1, u8g2_uint_t y1, u8g2_uint_t x2, u8g2_uint_t y2)
{
u8g2_uint_t tmp;
u8g2_uint_t x,y;
u8g2_uint_t dx, dy;
u8g2_int_t err;
u8g2_int_t ystep;
uint8_t swapxy = 0;
/* no intersection check at the moment, should be added... */
if ( x1 > x2 ) dx = x1-x2; else dx = x2-x1;
if ( y1 > y2 ) dy = y1-y2; else dy = y2-y1;
if ( dy > dx )
{
swapxy = 1;
tmp = dx; dx =dy; dy = tmp;
tmp = x1; x1 =y1; y1 = tmp;
tmp = x2; x2 =y2; y2 = tmp;
}
if ( x1 > x2 )
{
tmp = x1; x1 =x2; x2 = tmp;
tmp = y1; y1 =y2; y2 = tmp;
}
err = dx >> 1;
if ( y2 > y1 ) ystep = 1; else ystep = -1;
y = y1;
#ifndef U8G2_16BIT
if ( x2 == 255 )
x2--;
#else
if ( x2 == 0xffff )
x2--;
#endif
for( x = x1; x <= x2; x++ )
{
if ( swapxy == 0 )
u8g2_DrawPixel(u8g2, x, y);
else
u8g2_DrawPixel(u8g2, y, x);
err -= (uint8_t)dy;
if ( err < 0 )
{
y += (u8g2_uint_t)ystep;
err += (u8g2_uint_t)dx;
}
}
}

View File

@ -0,0 +1,368 @@
/*
u8g2_ll_hvline.c
low level hvline
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*ptr |= or_mask
*ptr ^= xor_mask
color = 0: or_mask = 1, xor_mask = 1
color = 1: or_mask = 1, xor_mask = 0
color = 2: or_mask = 0, xor_mask = 1
if ( color <= 1 )
or_mask = mask;
if ( color != 1 )
xor_mask = mask;
*/
#include "u8g2.h"
#include <assert.h>
/*=================================================*/
/*
u8g2_ll_hvline_vertical_top_lsb
SSD13xx
UC1701
*/
#ifdef U8G2_WITH_HVLINE_SPEED_OPTIMIZATION
/*
x,y Upper left position of the line within the local buffer (not the display!)
len length of the line in pixel, len must not be 0
dir 0: horizontal line (left to right)
1: vertical line (top to bottom)
asumption:
all clipping done
*/
void u8g2_ll_hvline_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
uint16_t offset;
uint8_t *ptr;
uint8_t bit_pos, mask;
uint8_t or_mask, xor_mask;
#ifdef __unix
uint8_t *max_ptr = u8g2->tile_buf_ptr + u8g2_GetU8x8(u8g2)->display_info->tile_width*u8g2->tile_buf_height*8;
#endif
//assert(x >= u8g2->buf_x0);
//assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
//assert(y >= u8g2->buf_y0);
//assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
/* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */
bit_pos = y; /* overflow truncate is ok here... */
bit_pos &= 7; /* ... because only the lowest 3 bits are needed */
mask = 1;
mask <<= bit_pos;
or_mask = 0;
xor_mask = 0;
if ( u8g2->draw_color <= 1 )
or_mask = mask;
if ( u8g2->draw_color != 1 )
xor_mask = mask;
offset = y; /* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */
offset &= ~7;
offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width;
ptr = u8g2->tile_buf_ptr;
ptr += offset;
ptr += x;
if ( dir == 0 )
{
do
{
#ifdef __unix
assert(ptr < max_ptr);
#endif
*ptr |= or_mask;
*ptr ^= xor_mask;
ptr++;
len--;
} while( len != 0 );
}
else
{
do
{
#ifdef __unix
assert(ptr < max_ptr);
#endif
*ptr |= or_mask;
*ptr ^= xor_mask;
bit_pos++;
bit_pos &= 7;
len--;
if ( bit_pos == 0 )
{
ptr+=u8g2->pixel_buf_width; /* 6 Jan 17: Changed u8g2->width to u8g2->pixel_buf_width, issue #148 */
if ( u8g2->draw_color <= 1 )
or_mask = 1;
if ( u8g2->draw_color != 1 )
xor_mask = 1;
}
else
{
or_mask <<= 1;
xor_mask <<= 1;
}
} while( len != 0 );
}
}
#else /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */
/*
x,y position within the buffer
*/
static void u8g2_draw_pixel_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y)
{
uint16_t offset;
uint8_t *ptr;
uint8_t bit_pos, mask;
//assert(x >= u8g2->buf_x0);
//assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
//assert(y >= u8g2->buf_y0);
//assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
/* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */
bit_pos = y; /* overflow truncate is ok here... */
bit_pos &= 7; /* ... because only the lowest 3 bits are needed */
mask = 1;
mask <<= bit_pos;
offset = y; /* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */
offset &= ~7;
offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width;
ptr = u8g2->tile_buf_ptr;
ptr += offset;
ptr += x;
if ( u8g2->draw_color <= 1 )
*ptr |= mask;
if ( u8g2->draw_color != 1 )
*ptr ^= mask;
}
/*
x,y Upper left position of the line within the local buffer (not the display!)
len length of the line in pixel, len must not be 0
dir 0: horizontal line (left to right)
1: vertical line (top to bottom)
asumption:
all clipping done
*/
void u8g2_ll_hvline_vertical_top_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
if ( dir == 0 )
{
do
{
u8g2_draw_pixel_vertical_top_lsb(u8g2, x, y);
x++;
len--;
} while( len != 0 );
}
else
{
do
{
u8g2_draw_pixel_vertical_top_lsb(u8g2, x, y);
y++;
len--;
} while( len != 0 );
}
}
#endif /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */
/*=================================================*/
/*
u8g2_ll_hvline_horizontal_right_lsb
ST7920
*/
#ifdef U8G2_WITH_HVLINE_SPEED_OPTIMIZATION
/*
x,y Upper left position of the line within the local buffer (not the display!)
len length of the line in pixel, len must not be 0
dir 0: horizontal line (left to right)
1: vertical line (top to bottom)
asumption:
all clipping done
*/
void u8g2_ll_hvline_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
uint16_t offset;
uint8_t *ptr;
uint8_t bit_pos;
uint8_t mask;
uint8_t tile_width = u8g2_GetU8x8(u8g2)->display_info->tile_width;
bit_pos = x; /* overflow truncate is ok here... */
bit_pos &= 7; /* ... because only the lowest 3 bits are needed */
mask = 128;
mask >>= bit_pos;
offset = y; /* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */
offset *= tile_width;
offset += x>>3;
ptr = u8g2->tile_buf_ptr;
ptr += offset;
if ( dir == 0 )
{
do
{
if ( u8g2->draw_color <= 1 )
*ptr |= mask;
if ( u8g2->draw_color != 1 )
*ptr ^= mask;
mask >>= 1;
if ( mask == 0 )
{
mask = 128;
ptr++;
}
//x++;
len--;
} while( len != 0 );
}
else
{
do
{
if ( u8g2->draw_color <= 1 )
*ptr |= mask;
if ( u8g2->draw_color != 1 )
*ptr ^= mask;
ptr += tile_width;
//y++;
len--;
} while( len != 0 );
}
}
#else /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */
/*
x,y position within the buffer
*/
static void u8g2_draw_pixel_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y)
{
uint16_t offset;
uint8_t *ptr;
uint8_t bit_pos, mask;
//assert(x >= u8g2->buf_x0);
//assert(x < u8g2_GetU8x8(u8g2)->display_info->tile_width*8);
//assert(y >= u8g2->buf_y0);
//assert(y < u8g2_GetU8x8(u8g2)->display_info->tile_height*8);
/* bytes are vertical, lsb on top (y=0), msb at bottom (y=7) */
bit_pos = x; /* overflow truncate is ok here... */
bit_pos &= 7; /* ... because only the lowest 3 bits are needed */
mask = 128;
mask >>= bit_pos;
x >>= 3;
offset = y; /* y might be 8 or 16 bit, but we need 16 bit, so use a 16 bit variable */
offset *= u8g2_GetU8x8(u8g2)->display_info->tile_width;
offset += x;
ptr = u8g2->tile_buf_ptr;
ptr += offset;
if ( u8g2->draw_color <= 1 )
*ptr |= mask;
if ( u8g2->draw_color != 1 )
*ptr ^= mask;
}
/*
x,y Upper left position of the line within the local buffer (not the display!)
len length of the line in pixel, len must not be 0
dir 0: horizontal line (left to right)
1: vertical line (top to bottom)
asumption:
all clipping done
*/
void u8g2_ll_hvline_horizontal_right_lsb(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
if ( dir == 0 )
{
do
{
u8g2_draw_pixel_horizontal_right_lsb(u8g2, x, y);
x++;
len--;
} while( len != 0 );
}
else
{
do
{
u8g2_draw_pixel_horizontal_right_lsb(u8g2, x, y);
y++;
len--;
} while( len != 0 );
}
}
#endif /* U8G2_WITH_HVLINE_SPEED_OPTIMIZATION */

View File

@ -0,0 +1,197 @@
/*
u8g2_message.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
#define SPACE_BETWEEN_BUTTONS_IN_PIXEL 6
#define SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL 3
uint8_t u8g2_draw_button_line(u8g2_t *u8g2, u8g2_uint_t y, u8g2_uint_t w, uint8_t cursor, const char *s)
{
u8g2_uint_t button_line_width;
uint8_t i;
uint8_t cnt;
uint8_t is_invert;
u8g2_uint_t d;
u8g2_uint_t x;
cnt = u8x8_GetStringLineCnt(s);
/* calculate the width of the button line */
button_line_width = 0;
for( i = 0; i < cnt; i++ )
{
button_line_width += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s));
}
button_line_width += (cnt-1)*SPACE_BETWEEN_BUTTONS_IN_PIXEL; /* add some space between the buttons */
/* calculate the left offset */
d = 0;
if ( button_line_width < w )
{
d = w;
d -= button_line_width;
d /= 2;
}
/* draw the buttons */
x = d;
for( i = 0; i < cnt; i++ )
{
is_invert = 0;
if ( i == cursor )
is_invert = 1;
u8g2_DrawUTF8Line(u8g2, x, y, 0, u8x8_GetStringLineStart(i, s), 1, is_invert);
x += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s));
x += SPACE_BETWEEN_BUTTONS_IN_PIXEL;
}
/* return the number of buttons */
return cnt;
}
/*
title1: Multiple lines,separated by '\n'
title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart()
title3: Multiple lines,separated by '\n'
buttons: one more more buttons separated by '\n' and terminated with '\0'
side effects:
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFontPosBaseline(u8g2);
*/
uint8_t u8g2_UserInterfaceMessage(u8g2_t *u8g2, const char *title1, const char *title2, const char *title3, const char *buttons)
{
uint8_t height;
uint8_t line_height;
u8g2_uint_t pixel_height;
u8g2_uint_t y, yy;
uint8_t cursor = 0;
uint8_t button_cnt;
uint8_t event;
/* only horizontal strings are supported, so force this here */
u8g2_SetFontDirection(u8g2, 0);
/* force baseline position */
u8g2_SetFontPosBaseline(u8g2);
/* calculate line height */
line_height = u8g2_GetAscent(u8g2);
line_height -= u8g2_GetDescent(u8g2);
/* calculate overall height of the message box in lines*/
height = 1; /* button line */
height += u8x8_GetStringLineCnt(title1);
if ( title2 != NULL )
height++;
height += u8x8_GetStringLineCnt(title3);
/* calculate the height in pixel */
pixel_height = height;
pixel_height *= line_height;
/* ... and add the space between the text and the buttons */
pixel_height +=SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL;
/* calculate offset from top */
y = 0;
if ( pixel_height < u8g2_GetDisplayHeight(u8g2) )
{
y = u8g2_GetDisplayHeight(u8g2);
y -= pixel_height;
y /= 2;
}
y += u8g2_GetAscent(u8g2);
for(;;)
{
u8g2_FirstPage(u8g2);
do
{
yy = y;
/* draw message box */
yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title1);
if ( title2 != NULL )
{
u8g2_DrawUTF8Line(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), title2, 0, 0);
yy+=line_height;
}
yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title3);
yy += SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL;
button_cnt = u8g2_draw_button_line(u8g2, yy, u8g2_GetDisplayWidth(u8g2), cursor, buttons);
} while( u8g2_NextPage(u8g2) );
#ifdef U8G2_REF_MAN_PIC
return 0;
#endif
for(;;)
{
event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2));
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
return cursor+1;
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
return 0;
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN )
{
cursor++;
if ( cursor >= button_cnt )
cursor = 0;
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP )
{
if ( cursor == 0 )
cursor = button_cnt;
cursor--;
break;
}
}
}
/* never reached */
//return 0;
}

View File

@ -0,0 +1,346 @@
/*
u8g22_polygon.c
*/
#include "u8g2.h"
/*===========================================*/
/* local definitions */
typedef int16_t pg_word_t;
struct pg_point_struct
{
pg_word_t x;
pg_word_t y;
};
typedef struct _pg_struct pg_struct; /* forward declaration */
struct pg_edge_struct
{
pg_word_t x_direction; /* 1, if x2 is greater than x1, -1 otherwise */
pg_word_t height;
pg_word_t current_x_offset;
pg_word_t error_offset;
/* --- line loop --- */
pg_word_t current_y;
pg_word_t max_y;
pg_word_t current_x;
pg_word_t error;
/* --- outer loop --- */
uint8_t (*next_idx_fn)(pg_struct *pg, uint8_t i);
uint8_t curr_idx;
};
/* maximum number of points in the polygon */
/* can be redefined, but highest possible value is 254 */
#define PG_MAX_POINTS 6
/* index numbers for the pge structures below */
#define PG_LEFT 0
#define PG_RIGHT 1
struct _pg_struct
{
struct pg_point_struct list[PG_MAX_POINTS];
uint8_t cnt;
uint8_t is_min_y_not_flat;
pg_word_t total_scan_line_cnt;
struct pg_edge_struct pge[2]; /* left and right line draw structures */
};
/*===========================================*/
/* procedures, which should not be inlined (save as much flash ROM as possible */
#define PG_NOINLINE U8G2_NOINLINE
static uint8_t pge_Next(struct pg_edge_struct *pge) PG_NOINLINE;
static uint8_t pg_inc(pg_struct *pg, uint8_t i) PG_NOINLINE;
static uint8_t pg_dec(pg_struct *pg, uint8_t i) PG_NOINLINE;
static void pg_expand_min_y(pg_struct *pg, pg_word_t min_y, uint8_t pge_idx) PG_NOINLINE;
static void pg_line_init(pg_struct * const pg, uint8_t pge_index) PG_NOINLINE;
/*===========================================*/
/* line draw algorithm */
static uint8_t pge_Next(struct pg_edge_struct *pge)
{
if ( pge->current_y >= pge->max_y )
return 0;
pge->current_x += pge->current_x_offset;
pge->error += pge->error_offset;
if ( pge->error > 0 )
{
pge->current_x += pge->x_direction;
pge->error -= pge->height;
}
pge->current_y++;
return 1;
}
/* assumes y2 > y1 */
static void pge_Init(struct pg_edge_struct *pge, pg_word_t x1, pg_word_t y1, pg_word_t x2, pg_word_t y2)
{
pg_word_t dx = x2 - x1;
pg_word_t width;
pge->height = y2 - y1;
pge->max_y = y2;
pge->current_y = y1;
pge->current_x = x1;
if ( dx >= 0 )
{
pge->x_direction = 1;
width = dx;
pge->error = 0;
}
else
{
pge->x_direction = -1;
width = -dx;
pge->error = 1 - pge->height;
}
pge->current_x_offset = dx / pge->height;
pge->error_offset = width % pge->height;
}
/*===========================================*/
/* convex polygon algorithm */
static uint8_t pg_inc(pg_struct *pg, uint8_t i)
{
i++;
if ( i >= pg->cnt )
i = 0;
return i;
}
static uint8_t pg_dec(pg_struct *pg, uint8_t i)
{
i--;
if ( i >= pg->cnt )
i = pg->cnt-1;
return i;
}
static void pg_expand_min_y(pg_struct *pg, pg_word_t min_y, uint8_t pge_idx)
{
uint8_t i = pg->pge[pge_idx].curr_idx;
for(;;)
{
i = pg->pge[pge_idx].next_idx_fn(pg, i);
if ( pg->list[i].y != min_y )
break;
pg->pge[pge_idx].curr_idx = i;
}
}
static uint8_t pg_prepare(pg_struct *pg)
{
pg_word_t max_y;
pg_word_t min_y;
uint8_t i;
/* setup the next index procedures */
pg->pge[PG_RIGHT].next_idx_fn = pg_inc;
pg->pge[PG_LEFT].next_idx_fn = pg_dec;
/* search for highest and lowest point */
max_y = pg->list[0].y;
min_y = pg->list[0].y;
pg->pge[PG_LEFT].curr_idx = 0;
for( i = 1; i < pg->cnt; i++ )
{
if ( max_y < pg->list[i].y )
{
max_y = pg->list[i].y;
}
if ( min_y > pg->list[i].y )
{
pg->pge[PG_LEFT].curr_idx = i;
min_y = pg->list[i].y;
}
}
/* calculate total number of scan lines */
pg->total_scan_line_cnt = max_y;
pg->total_scan_line_cnt -= min_y;
/* exit if polygon height is zero */
if ( pg->total_scan_line_cnt == 0 )
return 0;
/* if the minimum y side is flat, try to find the lowest and highest x points */
pg->pge[PG_RIGHT].curr_idx = pg->pge[PG_LEFT].curr_idx;
pg_expand_min_y(pg, min_y, PG_RIGHT);
pg_expand_min_y(pg, min_y, PG_LEFT);
/* check if the min side is really flat (depends on the x values) */
pg->is_min_y_not_flat = 1;
if ( pg->list[pg->pge[PG_LEFT].curr_idx].x != pg->list[pg->pge[PG_RIGHT].curr_idx].x )
{
pg->is_min_y_not_flat = 0;
}
else
{
pg->total_scan_line_cnt--;
if ( pg->total_scan_line_cnt == 0 )
return 0;
}
return 1;
}
static void pg_hline(pg_struct *pg, u8g2_t *u8g2)
{
pg_word_t x1, x2, y;
x1 = pg->pge[PG_LEFT].current_x;
x2 = pg->pge[PG_RIGHT].current_x;
y = pg->pge[PG_RIGHT].current_y;
if ( y < 0 )
return;
if ( y >= u8g2_GetDisplayHeight(u8g2) ) // does not work for 256x64 display???
return;
if ( x1 < x2 )
{
if ( x2 < 0 )
return;
if ( x1 >= u8g2_GetDisplayWidth(u8g2) )
return;
if ( x1 < 0 )
x1 = 0;
if ( x2 >= u8g2_GetDisplayWidth(u8g2) )
x2 = u8g2_GetDisplayWidth(u8g2);
u8g2_DrawHLine(u8g2, x1, y, x2 - x1);
}
else
{
if ( x1 < 0 )
return;
if ( x2 >= u8g2_GetDisplayWidth(u8g2) )
return;
if ( x2 < 0 )
x1 = 0;
if ( x1 >= u8g2_GetDisplayWidth(u8g2) )
x1 = u8g2_GetDisplayWidth(u8g2);
u8g2_DrawHLine(u8g2, x2, y, x1 - x2);
}
}
static void pg_line_init(pg_struct * const pg, uint8_t pge_index)
{
struct pg_edge_struct *pge = pg->pge+pge_index;
uint8_t idx;
pg_word_t x1;
pg_word_t y1;
pg_word_t x2;
pg_word_t y2;
idx = pge->curr_idx;
y1 = pg->list[idx].y;
x1 = pg->list[idx].x;
idx = pge->next_idx_fn(pg, idx);
y2 = pg->list[idx].y;
x2 = pg->list[idx].x;
pge->curr_idx = idx;
pge_Init(pge, x1, y1, x2, y2);
}
static void pg_exec(pg_struct *pg, u8g2_t *u8g2)
{
pg_word_t i = pg->total_scan_line_cnt;
/* first line is skipped if the min y line is not flat */
pg_line_init(pg, PG_LEFT);
pg_line_init(pg, PG_RIGHT);
if ( pg->is_min_y_not_flat != 0 )
{
pge_Next(&(pg->pge[PG_LEFT]));
pge_Next(&(pg->pge[PG_RIGHT]));
}
do
{
pg_hline(pg, u8g2);
while ( pge_Next(&(pg->pge[PG_LEFT])) == 0 )
{
pg_line_init(pg, PG_LEFT);
}
while ( pge_Next(&(pg->pge[PG_RIGHT])) == 0 )
{
pg_line_init(pg, PG_RIGHT);
}
i--;
} while( i > 0 );
}
/*===========================================*/
/* API procedures */
static void pg_ClearPolygonXY(pg_struct *pg)
{
pg->cnt = 0;
}
static void pg_AddPolygonXY(pg_struct *pg, int16_t x, int16_t y)
{
if ( pg->cnt < PG_MAX_POINTS )
{
pg->list[pg->cnt].x = x;
pg->list[pg->cnt].y = y;
pg->cnt++;
}
}
static void pg_DrawPolygon(pg_struct *pg, u8g2_t *u8g2)
{
if ( pg_prepare(pg) == 0 )
return;
pg_exec(pg, u8g2);
}
pg_struct u8g2_pg;
void u8g2_ClearPolygonXY(void)
{
pg_ClearPolygonXY(&u8g2_pg);
}
void u8g2_AddPolygonXY(U8X8_UNUSED u8g2_t *u8g2, int16_t x, int16_t y)
{
pg_AddPolygonXY(&u8g2_pg, x, y);
}
void u8g2_DrawPolygon(u8g2_t *u8g2)
{
pg_DrawPolygon(&u8g2_pg, u8g2);
}
void u8g2_DrawTriangle(u8g2_t *u8g2, int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
u8g2_ClearPolygonXY();
u8g2_AddPolygonXY(u8g2, x0, y0);
u8g2_AddPolygonXY(u8g2, x1, y1);
u8g2_AddPolygonXY(u8g2, x2, y2);
u8g2_DrawPolygon(u8g2);
}

View File

@ -0,0 +1,284 @@
/*
u8g2_selection_list.c
selection list with scroll option
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
#define MY_BORDER_SIZE 1
/*
Draw a string at x,y
Center string within w (left adjust if w < pixel len of s)
Side effects:
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFontPosBaseline(u8g2);
*/
void u8g2_DrawUTF8Line(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, const char *s, uint8_t border_size, uint8_t is_invert)
{
u8g2_uint_t d, str_width;
u8g2_uint_t fx, fy, fw, fh;
/* only horizontal strings are supported, so force this here */
u8g2_SetFontDirection(u8g2, 0);
/* revert y position back to baseline ref */
y += u8g2->font_calc_vref(u8g2);
/* calculate the width of the string in pixel */
str_width = u8g2_GetUTF8Width(u8g2, s);
/* calculate delta d within the box */
d = 0;
if ( str_width < w )
{
d = w;
d -=str_width;
d /= 2;
}
else
{
w = str_width;
}
/* caluclate text box */
fx = x;
fy = y - u8g2_GetAscent(u8g2) ;
fw = w;
fh = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) ;
/* draw the box, if inverted */
u8g2_SetDrawColor(u8g2, 1);
if ( is_invert )
{
u8g2_DrawBox(u8g2, fx, fy, fw, fh);
}
/* draw the frame */
while( border_size > 0 )
{
fx--;
fy--;
fw +=2;
fh +=2;
u8g2_DrawFrame(u8g2, fx, fy, fw, fh );
border_size--;
}
if ( is_invert )
{
u8g2_SetDrawColor(u8g2, 0);
}
else
{
u8g2_SetDrawColor(u8g2, 1);
}
/* draw the text */
u8g2_DrawUTF8(u8g2, x+d, y, s);
/* revert draw color */
u8g2_SetDrawColor(u8g2, 1);
}
/*
draw several lines at position x,y.
lines are stored in s and must be separated with '\n'.
lines can be centered with respect to "w"
if s == NULL nothing is drawn and 0 is returned
returns the number of lines in s multiplied with line_height
*/
u8g2_uint_t u8g2_DrawUTF8Lines(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t line_height, const char *s)
{
uint8_t i;
uint8_t cnt;
u8g2_uint_t yy = 0;
cnt = u8x8_GetStringLineCnt(s);
//printf("str=%s\n", s);
//printf("cnt=%d, y=%d, line_height=%d\n", cnt, y, line_height);
for( i = 0; i < cnt; i++ )
{
//printf(" i=%d, y=%d, line_height=%d\n", i, y, line_height);
u8g2_DrawUTF8Line(u8g2, x, y, w, u8x8_GetStringLineStart(i, s), 0, 0);
y+=line_height;
yy+=line_height;
}
return yy;
}
/*
selection list with string line
returns line height
*/
static u8g2_uint_t u8g2_draw_selection_list_line(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, uint8_t idx, const char *s) U8G2_NOINLINE;
static u8g2_uint_t u8g2_draw_selection_list_line(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, uint8_t idx, const char *s)
{
u8g2_uint_t yy;
uint8_t border_size = 0;
uint8_t is_invert = 0;
u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2)+MY_BORDER_SIZE;
/* calculate offset from display upper border */
yy = idx;
yy -= u8sl->first_pos;
yy *= line_height;
yy += y;
/* check whether this is the current cursor line */
if ( idx == u8sl->current_pos )
{
border_size = MY_BORDER_SIZE;
is_invert = 1;
}
/* get the line from the array */
s = u8x8_GetStringLineStart(idx, s);
/* draw the line */
if ( s == NULL )
s = "";
u8g2_DrawUTF8Line(u8g2, MY_BORDER_SIZE, y, u8g2_GetDisplayWidth(u8g2)-2*MY_BORDER_SIZE, s, border_size, is_invert);
return line_height;
}
void u8g2_DrawSelectionList(u8g2_t *u8g2, u8sl_t *u8sl, u8g2_uint_t y, const char *s)
{
uint8_t i;
for( i = 0; i < u8sl->visible; i++ )
{
y += u8g2_draw_selection_list_line(u8g2, u8sl, y, i+u8sl->first_pos, s);
}
}
/*
title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n'
start_pos: default position for the cursor, first line is 1.
sl: string list (list of strings separated by \n)
returns 0 if user has pressed the home key
returns the selected line if user has pressed the select key
side effects:
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFontPosBaseline(u8g2);
*/
uint8_t u8g2_UserInterfaceSelectionList(u8g2_t *u8g2, const char *title, uint8_t start_pos, const char *sl)
{
u8sl_t u8sl;
u8g2_uint_t yy;
uint8_t event;
u8g2_uint_t line_height = u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2)+MY_BORDER_SIZE;
uint8_t title_lines = u8x8_GetStringLineCnt(title);
uint8_t display_lines;
if ( start_pos > 0 ) /* issue 112 */
start_pos--; /* issue 112 */
if ( title_lines > 0 )
{
display_lines = (u8g2_GetDisplayHeight(u8g2)-3) / line_height;
u8sl.visible = display_lines;
u8sl.visible -= title_lines;
}
else
{
display_lines = u8g2_GetDisplayHeight(u8g2) / line_height;
u8sl.visible = display_lines;
}
u8sl.total = u8x8_GetStringLineCnt(sl);
u8sl.first_pos = 0;
u8sl.current_pos = start_pos;
if ( u8sl.current_pos >= u8sl.total )
u8sl.current_pos = u8sl.total-1;
if ( u8sl.first_pos+u8sl.visible <= u8sl.current_pos )
u8sl.first_pos = u8sl.current_pos-u8sl.visible+1;
u8g2_SetFontPosBaseline(u8g2);
for(;;)
{
u8g2_FirstPage(u8g2);
do
{
yy = u8g2_GetAscent(u8g2);
if ( title_lines > 0 )
{
yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title);
u8g2_DrawHLine(u8g2, 0, yy-line_height- u8g2_GetDescent(u8g2) + 1, u8g2_GetDisplayWidth(u8g2));
yy += 3;
}
u8g2_DrawSelectionList(u8g2, &u8sl, yy, sl);
} while( u8g2_NextPage(u8g2) );
#ifdef U8G2_REF_MAN_PIC
return 0;
#endif
for(;;)
{
event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2));
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
return u8sl.current_pos+1; /* +1, issue 112 */
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
return 0; /* issue 112: return 0 instead of start_pos */
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN )
{
u8sl_Next(&u8sl);
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP )
{
u8sl_Prev(&u8sl);
break;
}
}
}
}

View File

@ -0,0 +1,441 @@
/*
u8g2_setup.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
#include <string.h>
#include <assert.h>
/*============================================*/
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
void u8g2_SetMaxClipWindow(u8g2_t *u8g2)
{
u8g2->clip_x0 = 0;
u8g2->clip_y0 = 0;
u8g2->clip_x1 = (u8g2_uint_t)~(u8g2_uint_t)0;
u8g2->clip_y1 = (u8g2_uint_t)~(u8g2_uint_t)0;
u8g2->cb->update_page_win(u8g2);
}
void u8g2_SetClipWindow(u8g2_t *u8g2, u8g2_uint_t clip_x0, u8g2_uint_t clip_y0, u8g2_uint_t clip_x1, u8g2_uint_t clip_y1 )
{
u8g2->clip_x0 = clip_x0;
u8g2->clip_y0 = clip_y0;
u8g2->clip_x1 = clip_x1;
u8g2->clip_y1 = clip_y1;
u8g2->cb->update_page_win(u8g2);
}
#endif
/*============================================*/
/*
This procedure is called after setting up the display (u8x8 structure).
--> This is the central init procedure for u8g2 object
*/
void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, u8g2_draw_ll_hvline_cb ll_hvline_cb, const u8g2_cb_t *u8g2_cb)
{
u8g2->font = NULL;
//u8g2->kerning = NULL;
//u8g2->get_kerning_cb = u8g2_GetNullKerning;
//u8g2->ll_hvline = u8g2_ll_hvline_vertical_top_lsb;
u8g2->ll_hvline = ll_hvline_cb;
u8g2->tile_buf_ptr = buf;
u8g2->tile_buf_height = tile_buf_height;
u8g2->tile_curr_row = 0;
u8g2->font_decode.is_transparent = 0; /* issue 443 */
u8g2->bitmap_transparency = 0;
u8g2->draw_color = 1;
u8g2->is_auto_page_clear = 1;
u8g2->cb = u8g2_cb;
u8g2->cb->update_dimension(u8g2);
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_SetMaxClipWindow(u8g2); /* assign a clip window and call the update() procedure */
#else
u8g2->cb->update_page_win(u8g2);
#endif
u8g2_SetFontPosBaseline(u8g2); /* issue 195 */
#ifdef U8G2_WITH_FONT_ROTATION
u8g2->font_decode.dir = 0;
#endif
}
/*
Usually the display rotation is set initially, but it could be done later also
u8g2_cb can be U8G2_R0..U8G2_R3
*/
void u8g2_SetDisplayRotation(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb)
{
u8g2->cb = u8g2_cb;
u8g2->cb->update_dimension(u8g2);
u8g2->cb->update_page_win(u8g2);
}
/*============================================*/
/*
update dimension:
calculate the following variables:
u8g2_uint_t buf_x0; left corner of the buffer
u8g2_uint_t buf_x1; right corner of the buffer (excluded)
u8g2_uint_t buf_y0;
u8g2_uint_t buf_y1;
*/
static void u8g2_update_dimension_common(u8g2_t *u8g2)
{
const u8x8_display_info_t *display_info = u8g2_GetU8x8(u8g2)->display_info;
u8g2_uint_t t;
t = u8g2->tile_buf_height;
t *= 8;
u8g2->pixel_buf_height = t;
t = display_info->tile_width;
#ifndef U8G2_16BIT
if ( t >= 32 )
t = 31;
#endif
t *= 8;
u8g2->pixel_buf_width = t;
t = u8g2->tile_curr_row;
t *= 8;
u8g2->pixel_curr_row = t;
t = u8g2->tile_buf_height;
/* handle the case, where the buffer is larger than the (remaining) part of the display */
if ( t + u8g2->tile_curr_row > display_info->tile_height )
t = display_info->tile_height - u8g2->tile_curr_row;
t *= 8;
u8g2->buf_y0 = u8g2->pixel_curr_row;
u8g2->buf_y1 = u8g2->buf_y0;
u8g2->buf_y1 += t;
#ifdef U8G2_16BIT
u8g2->width = display_info->pixel_width;
u8g2->height = display_info->pixel_height;
#else
u8g2->width = 240;
if ( display_info->pixel_width <= 240 )
u8g2->width = display_info->pixel_width;
u8g2->height = display_info->pixel_height;
#endif
}
/*==========================================================*/
/* apply clip window */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
static void u8g2_apply_clip_window(u8g2_t *u8g2)
{
/* check aganst the current user_??? window */
if ( u8g2_IsIntersection(u8g2, u8g2->clip_x0, u8g2->clip_y0, u8g2->clip_x1, u8g2->clip_y1) == 0 )
{
u8g2->is_page_clip_window_intersection = 0;
}
else
{
u8g2->is_page_clip_window_intersection = 1;
if ( u8g2->user_x0 < u8g2->clip_x0 )
u8g2->user_x0 = u8g2->clip_x0;
if ( u8g2->user_x1 > u8g2->clip_x1 )
u8g2->user_x1 = u8g2->clip_x1;
if ( u8g2->user_y0 < u8g2->clip_y0 )
u8g2->user_y0 = u8g2->clip_y0;
if ( u8g2->user_y1 > u8g2->clip_y1 )
u8g2->user_y1 = u8g2->clip_y1;
}
}
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
/*==========================================================*/
void u8g2_update_dimension_r0(u8g2_t *u8g2)
{
u8g2_update_dimension_common(u8g2);
}
void u8g2_update_page_win_r0(u8g2_t *u8g2)
{
u8g2->user_x0 = 0;
u8g2->user_x1 = u8g2->width; /* pixel_buf_width replaced with width */
u8g2->user_y0 = u8g2->buf_y0;
u8g2->user_y1 = u8g2->buf_y1;
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_apply_clip_window(u8g2);
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
}
void u8g2_update_dimension_r1(u8g2_t *u8g2)
{
u8g2_update_dimension_common(u8g2);
u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_width;
u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_height;
}
void u8g2_update_page_win_r1(u8g2_t *u8g2)
{
u8g2->user_x0 = u8g2->buf_y0;
u8g2->user_x1 = u8g2->buf_y1;
u8g2->user_y0 = 0;
u8g2->user_y1 = u8g2->height; /* pixel_buf_width replaced with height (which is the real pixel width) */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_apply_clip_window(u8g2);
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
}
void u8g2_update_dimension_r2(u8g2_t *u8g2)
{
u8g2_update_dimension_common(u8g2);
}
void u8g2_update_page_win_r2(u8g2_t *u8g2)
{
u8g2->user_x0 = 0;
u8g2->user_x1 = u8g2->width; /* pixel_buf_width replaced with width */
/* there are ases where the height is not a multiple of 8. */
/* in such a case u8g2->buf_y1 might be heigher than u8g2->height */
u8g2->user_y0 = 0;
if ( u8g2->height >= u8g2->buf_y1 )
u8g2->user_y0 = u8g2->height - u8g2->buf_y1;
u8g2->user_y1 = u8g2->height - u8g2->buf_y0;
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_apply_clip_window(u8g2);
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
}
void u8g2_update_dimension_r3(u8g2_t *u8g2)
{
u8g2_update_dimension_common(u8g2);
u8g2->height = u8g2_GetU8x8(u8g2)->display_info->pixel_width;
u8g2->width = u8g2_GetU8x8(u8g2)->display_info->pixel_height;
}
void u8g2_update_page_win_r3(u8g2_t *u8g2)
{
/* there are ases where the height is not a multiple of 8. */
/* in such a case u8g2->buf_y1 might be heigher than u8g2->width */
u8g2->user_x0 = 0;
if ( u8g2->width >= u8g2->buf_y1 )
u8g2->user_x0 = u8g2->width - u8g2->buf_y1;
u8g2->user_x1 = u8g2->width - u8g2->buf_y0;
u8g2->user_y0 = 0;
u8g2->user_y1 = u8g2->height; /* pixel_buf_width replaced with height (pixel_width) */
#ifdef U8G2_WITH_CLIP_WINDOW_SUPPORT
u8g2_apply_clip_window(u8g2);
#endif /* U8G2_WITH_CLIP_WINDOW_SUPPORT */
}
/*============================================*/
extern void u8g2_draw_hv_line_2dir(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir);
void u8g2_draw_l90_r0(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
#ifdef __unix
assert( dir <= 1 );
#endif
u8g2_draw_hv_line_2dir(u8g2, x, y, len, dir);
}
void u8g2_draw_l90_mirrorr_r0(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
u8g2_uint_t xx;
xx = u8g2->width;
xx -= x;
if ( (dir & 1) == 0 )
{
xx -= len;
}
else
{
xx--;
}
u8g2_draw_hv_line_2dir(u8g2, xx, y, len, dir);
}
/* dir = 0 or 1 */
void u8g2_draw_l90_r1(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
u8g2_uint_t xx, yy;
#ifdef __unix
assert( dir <= 1 );
#endif
yy = x;
xx = u8g2->height;
xx -= y;
xx--;
dir ++;
if ( dir == 2 )
{
xx -= len;
xx++;
dir = 0;
}
u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir);
}
void u8g2_draw_l90_r2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
u8g2_uint_t xx, yy;
/*
yy = u8g2->height;
yy -= y;
yy--;
xx = u8g2->width;
xx -= x;
xx--;
if ( dir == 0 )
{
xx -= len;
xx++;
}
else if ( dir == 1 )
{
yy -= len;
yy++;
}
*/
yy = u8g2->height;
yy -= y;
xx = u8g2->width;
xx -= x;
if ( dir == 0 )
{
yy--;
xx -= len;
}
else if ( dir == 1 )
{
xx--;
yy -= len;
}
u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir);
}
void u8g2_draw_l90_r3(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, uint8_t dir)
{
u8g2_uint_t xx, yy;
xx = y;
yy = u8g2->width;
yy -= x;
if ( dir == 0 )
{
yy--;
yy -= len;
yy++;
dir = 1;
}
else
{
yy--;
dir = 0;
}
u8g2_draw_hv_line_2dir(u8g2, xx, yy, len, dir);
}
/*============================================*/
const u8g2_cb_t u8g2_cb_r0 = { u8g2_update_dimension_r0, u8g2_update_page_win_r0, u8g2_draw_l90_r0 };
const u8g2_cb_t u8g2_cb_r1 = { u8g2_update_dimension_r1, u8g2_update_page_win_r1, u8g2_draw_l90_r1 };
const u8g2_cb_t u8g2_cb_r2 = { u8g2_update_dimension_r2, u8g2_update_page_win_r2, u8g2_draw_l90_r2 };
const u8g2_cb_t u8g2_cb_r3 = { u8g2_update_dimension_r3, u8g2_update_page_win_r3, u8g2_draw_l90_r3 };
const u8g2_cb_t u8g2_cb_mirror = { u8g2_update_dimension_r0, u8g2_update_page_win_r0, u8g2_draw_l90_mirrorr_r0 };
/*============================================*/
/* setup for the null device */
/* setup for the null (empty) device */
void u8g2_Setup_null(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
{
static uint8_t buf[8];
u8g2_SetupDisplay(u8g2, u8x8_d_null_cb, u8x8_cad_empty, byte_cb, gpio_and_delay_cb);
u8g2_SetupBuffer(u8g2, buf, 1, u8g2_ll_hvline_vertical_top_lsb, rotation);
}

View File

@ -0,0 +1,260 @@
/*
u8log.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdint.h>
#include <string.h>
#include "u8x8.h"
/*
static uint8_t u8log_is_on_screen(u8log_t *u8log, uint8_t x, uint8_t y)
{
if ( x >= u8log->width )
return 0;
if ( y >= u8log->height )
return 0;
return 1;
}
*/
static void u8log_clear_screen(u8log_t *u8log)
{
uint8_t *dest = u8log->screen_buffer;
uint16_t cnt = u8log->height;
cnt *= u8log->width;
do
{
*dest++ = ' ';
cnt--;
} while( cnt > 0 );
}
/* scroll the content of the complete buffer, set redraw_line to 255 */
static void u8log_scroll_up(u8log_t *u8log)
{
uint8_t *dest = u8log->screen_buffer;
uint8_t *src = dest+u8log->width;
uint16_t cnt = u8log->height;
cnt--;
cnt *= u8log->width;
do
{
*dest++ = *src++;
cnt--;
} while( cnt > 0 );
cnt = u8log->width;
do
{
*dest++ = ' ';
cnt--;
} while(cnt > 0);
if ( u8log->is_redraw_line_for_each_char )
u8log->is_redraw_all = 1;
else
u8log->is_redraw_all_required_for_next_nl = 1;
}
/*
Place the cursor on the screen. This will also scroll, if required
*/
static void u8log_cursor_on_screen(u8log_t *u8log)
{
//printf("u8log_cursor_on_screen, cursor_y=%d\n", u8log->cursor_y);
if ( u8log->cursor_x >= u8log->width )
{
u8log->cursor_x = 0;
u8log->cursor_y++;
}
while ( u8log->cursor_y >= u8log->height )
{
u8log_scroll_up(u8log);
u8log->cursor_y--;
}
}
/*
Write a printable, single char on the screen, do any kind of scrolling
*/
static void u8log_write_to_screen(u8log_t *u8log, uint8_t c)
{
u8log_cursor_on_screen(u8log);
u8log->screen_buffer[u8log->cursor_y * u8log->width + u8log->cursor_x] = c;
u8log->cursor_x++;
if ( u8log->is_redraw_line_for_each_char )
{
u8log->is_redraw_line = 1;
u8log->redraw_line = u8log->cursor_y;
}
}
/*
Handle control codes or write the char to the screen.
Supported control codes are:
\n 10 Goto first position of the next line. Line is marked for redraw.
\r 13 Goto first position in the same line. Line is marked for redraw.
\t 9 Jump to the next tab position
\f 12 Clear the screen and mark redraw for whole screen
any other char Write char to screen. Line redraw mark depends on
is_redraw_line_for_each_char flag.
*/
void u8log_write_char(u8log_t *u8log, uint8_t c)
{
switch(c)
{
case '\n': // 10
u8log->is_redraw_line = 1;
u8log->redraw_line = u8log->cursor_y;
if ( u8log->is_redraw_all_required_for_next_nl )
u8log->is_redraw_all = 1;
u8log->is_redraw_all_required_for_next_nl = 0;
u8log->cursor_y++;
u8log->cursor_x = 0;
break;
case '\r': // 13
u8log->is_redraw_line = 1;
u8log->redraw_line = u8log->cursor_y;
u8log->cursor_x = 0;
break;
case '\t': // 9
u8log->cursor_x = (u8log->cursor_x + 8) & 0xf8;
break;
case '\f': // 12
u8log_clear_screen(u8log);
u8log->is_redraw_all = 1;
u8log->cursor_x = 0;
u8log->cursor_y = 0;
break;
default:
u8log_write_to_screen(u8log, c);
break;
}
}
void u8log_Init(u8log_t *u8log, uint8_t width, uint8_t height, uint8_t *buf)
{
memset(u8log, 0, sizeof(u8log_t));
u8log->width = width;
u8log->height = height;
u8log->screen_buffer = buf;
u8log_clear_screen(u8log);
}
void u8log_SetCallback(u8log_t *u8log, u8log_cb cb, void *aux_data)
{
u8log->cb = cb;
u8log->aux_data = aux_data;
}
void u8log_SetRedrawMode(u8log_t *u8log, uint8_t is_redraw_line_for_each_char)
{
u8log->is_redraw_line_for_each_char = is_redraw_line_for_each_char;
}
/* offset can be negative or positive, it is 0 by default */
void u8log_SetLineHeightOffset(u8log_t *u8log, int8_t line_height_offset)
{
u8log->line_height_offset = line_height_offset;
}
void u8log_WriteChar(u8log_t *u8log, uint8_t c)
{
u8log_write_char(u8log, c);
if ( u8log->is_redraw_line || u8log->is_redraw_all )
{
if ( u8log->cb != 0 )
{
u8log->cb(u8log);
}
u8log->is_redraw_line = 0;
u8log->is_redraw_all = 0;
}
}
void u8log_WriteString(u8log_t *u8log, const char *s)
{
while( *s != '\0' )
{
u8log_WriteChar(u8log, *s);
s++;
}
}
static void u8log_WriteHexHalfByte(u8log_t *u8log, uint8_t b) U8X8_NOINLINE;
static void u8log_WriteHexHalfByte(u8log_t *u8log, uint8_t b)
{
b &= 0x0f;
if ( b < 10 )
u8log_WriteChar(u8log, b+'0');
else
u8log_WriteChar(u8log, b+'a'-10);
}
void u8log_WriteHex8(u8log_t *u8log, uint8_t b)
{
u8log_WriteHexHalfByte(u8log, b >> 4);
u8log_WriteHexHalfByte(u8log, b);
}
void u8log_WriteHex16(u8log_t *u8log, uint16_t v)
{
u8log_WriteHex8(u8log, v>>8);
u8log_WriteHex8(u8log, v);
}
void u8log_WriteHex32(u8log_t *u8log, uint32_t v)
{
u8log_WriteHex16(u8log, v>>16);
u8log_WriteHex16(u8log, v);
}
/* v = value, d = number of digits (1..3) */
void u8log_WriteDec8(u8log_t *u8log, uint8_t v, uint8_t d)
{
u8log_WriteString(u8log, u8x8_u8toa(v, d));
}
/* v = value, d = number of digits (1..5) */
void u8log_WriteDec16(u8log_t *u8log, uint16_t v, uint8_t d)
{
u8log_WriteString(u8log, u8x8_u16toa(v, d));
}

View File

@ -0,0 +1,98 @@
/*
u8log_u8g2.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
/*
Draw the u8log text at the specified x/y position.
x/y position is the reference position of the first char of the first line.
the line height is
u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) + line_height_offset;
line_height_offset can be set with u8log_SetLineHeightOffset()
Use
u8g2_SetFontRefHeightText(u8g2_t *u8g2);
u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2);
u8g2_SetFontRefHeightAll(u8g2_t *u8g2);
to change the return values for u8g2_GetAscent and u8g2_GetDescent
*/
void u8g2_DrawLog(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8log_t *u8log)
{
u8g2_uint_t disp_x, disp_y;
uint8_t buf_x, buf_y;
uint8_t c;
disp_y = y;
u8g2_SetFontDirection(u8g2, 0);
for( buf_y = 0; buf_y < u8log->height; buf_y++ )
{
disp_x = x;
for( buf_x = 0; buf_x < u8log->width; buf_x++ )
{
c = u8log->screen_buffer[buf_y * u8log->width + buf_x];
disp_x += u8g2_DrawGlyph(u8g2, disp_x, disp_y, c);
}
disp_y += u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2);
disp_y += u8log->line_height_offset;
}
}
/*
u8lib callback for u8g2
Only font direction 0 is supported: u8g2_SetFontDirection(u8g2, 0)
Use
u8g2_SetFontRefHeightText(u8g2_t *u8g2);
u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2);
u8g2_SetFontRefHeightAll(u8g2_t *u8g2);
to change the top offset and the line height and
u8log_SetLineHeightOffset(u8log_t *u8log, int8_t line_height_offset)
to change the line height.
*/
void u8log_u8g2_cb(u8log_t * u8log)
{
u8g2_t *u8g2 = (u8g2_t *)(u8log->aux_data);
if ( u8log->is_redraw_line || u8log->is_redraw_all )
{
u8g2_FirstPage(u8g2);
do
{
u8g2_DrawLog( u8g2, 0, u8g2_GetAscent(u8g2), u8log);
}
while( u8g2_NextPage(u8g2) );
}
}

View File

@ -0,0 +1,75 @@
/*
u8log_u8x8.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static void u8x8_DrawLogLine(u8x8_t *u8x8, uint8_t disp_x, uint8_t disp_y, uint8_t buf_y, u8log_t *u8log) U8X8_NOINLINE;
static void u8x8_DrawLogLine(u8x8_t *u8x8, uint8_t disp_x, uint8_t disp_y, uint8_t buf_y, u8log_t *u8log)
{
uint8_t buf_x;
uint8_t c;
for( buf_x = 0; buf_x < u8log->width; buf_x++ )
{
c = u8log->screen_buffer[buf_y * u8log->width + buf_x];
u8x8_DrawGlyph(u8x8, disp_x, disp_y, c);
disp_x++;
}
}
void u8x8_DrawLog(u8x8_t *u8x8, uint8_t x, uint8_t y, u8log_t *u8log)
{
uint8_t buf_y;
for( buf_y = 0; buf_y < u8log->height; buf_y++ )
{
u8x8_DrawLogLine(u8x8, x, y, buf_y, u8log);
y++;
}
}
void u8log_u8x8_cb(u8log_t * u8log)
{
u8x8_t *u8x8 = (u8x8_t *)(u8log->aux_data);
if ( u8log->is_redraw_all )
{
u8x8_DrawLog(u8x8, 0, 0, u8log);
}
else if ( u8log->is_redraw_line )
{
u8x8_DrawLogLine(u8x8, 0, u8log->redraw_line, u8log->redraw_line, u8log);
}
}

1147
components/u8g2/csrc/u8x8.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,488 @@
/*
u8x8_8x8.c
font procedures, directly interfaces display procedures
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
#if defined(ESP8266)
uint8_t u8x8_pgm_read_esp(const uint8_t * addr)
{
uint32_t bytes;
bytes = *(uint32_t*)((uint32_t)addr & ~3);
return ((uint8_t*)&bytes)[(uint32_t)addr & 3];
}
#endif
void u8x8_SetFont(u8x8_t *u8x8, const uint8_t *font_8x8)
{
u8x8->font = font_8x8;
}
/*
Args:
u8x8: ptr to u8x8 structure
encoding: glyph for which the data is requested (must be between 0 and 255)
buf: pointer to 8 bytes
*/
static void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset) U8X8_NOINLINE;
static void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset)
{
uint8_t first, last, tiles, i;
uint16_t offset;
first = u8x8_pgm_read(u8x8->font+0);
last = u8x8_pgm_read(u8x8->font+1);
tiles = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
tiles *= u8x8_pgm_read(u8x8->font+3); /* new 2019 format */
/* get the glyph bitmap from the font */
if ( first <= encoding && encoding <= last )
{
offset = encoding;
offset -= first;
offset *= tiles; /* new 2019 format */
offset += tile_offset; /* new 2019 format */
offset *= 8;
offset +=4; /* changed from 2 to 4, new 2019 format */
for( i = 0; i < 8; i++ )
{
buf[i] = u8x8_pgm_read(u8x8->font+offset);
offset++;
}
}
else
{
for( i = 0; i < 8; i++ )
{
buf[i] = 0;
}
}
/* invert the bitmap if required */
if ( u8x8->is_font_inverse_mode )
{
for( i = 0; i < 8; i++ )
{
buf[i] ^= 255;
}
}
}
void u8x8_DrawGlyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
{
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
uint8_t tv = u8x8_pgm_read(u8x8->font+3); /* new 2019 format */
uint8_t xx, tile;
uint8_t buf[8];
th += x;
tv += y;
tile = 0;
do
{
xx = x;
do
{
u8x8_get_glyph_data(u8x8, encoding, buf, tile);
u8x8_DrawTile(u8x8, xx, y, 1, buf);
tile++;
xx++;
} while( xx < th );
y++;
} while( y < tv );
}
/*
Source: http://graphics.stanford.edu/~seander/bithacks.html
Section: Interleave bits by Binary Magic Numbers
Original codes is here:
static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF};
static const unsigned int S[] = {1, 2, 4, 8};
unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x
unsigned int y; // are in the even positions and bits from y in the odd;
unsigned int z; // z gets the resulting 32-bit Morton Number.
// x and y must initially be less than 65536.
x = (x | (x << S[3])) & B[3];
x = (x | (x << S[2])) & B[2];
x = (x | (x << S[1])) & B[1];
x = (x | (x << S[0])) & B[0];
y = (y | (y << S[3])) & B[3];
y = (y | (y << S[2])) & B[2];
y = (y | (y << S[1])) & B[1];
y = (y | (y << S[0])) & B[0];
z = x | (y << 1);
*/
uint16_t u8x8_upscale_byte(uint8_t x)
{
uint16_t y = x;
y |= (y << 4); // x = (x | (x << S[2])) & B[2];
y &= 0x0f0f;
y |= (y << 2); // x = (x | (x << S[1])) & B[1];
y &= 0x3333;
y |= (y << 1); // x = (x | (x << S[0])) & B[0];
y &= 0x5555;
y |= (y << 1); // z = x | (y << 1);
return y;
}
static void u8x8_upscale_buf(uint8_t *src, uint8_t *dest) U8X8_NOINLINE;
static void u8x8_upscale_buf(uint8_t *src, uint8_t *dest)
{
uint8_t i = 4;
do
{
*dest++ = *src;
*dest++ = *src++;
i--;
} while( i > 0 );
}
static void u8x8_draw_2x2_subglyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding, uint8_t tile)
{
uint8_t i;
uint16_t t;
uint8_t buf[8];
uint8_t buf1[8];
uint8_t buf2[8];
u8x8_get_glyph_data(u8x8, encoding, buf, tile);
for( i = 0; i < 8; i ++ )
{
t = u8x8_upscale_byte(buf[i]);
buf1[i] = t >> 8;
buf2[i] = t & 255;
}
u8x8_upscale_buf(buf2, buf);
u8x8_DrawTile(u8x8, x, y, 1, buf);
u8x8_upscale_buf(buf2+4, buf);
u8x8_DrawTile(u8x8, x+1, y, 1, buf);
u8x8_upscale_buf(buf1, buf);
u8x8_DrawTile(u8x8, x, y+1, 1, buf);
u8x8_upscale_buf(buf1+4, buf);
u8x8_DrawTile(u8x8, x+1, y+1, 1, buf);
}
void u8x8_Draw2x2Glyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
{
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
uint8_t tv = u8x8_pgm_read(u8x8->font+3); /* new 2019 format */
uint8_t xx, tile;
th *= 2;
th += x;
tv *= 2;
tv += y;
tile = 0;
do
{
xx = x;
do
{
u8x8_draw_2x2_subglyph(u8x8, xx, y, encoding, tile);
tile++;
xx+=2;
} while( xx < th );
y+=2;
} while( y < tv );
}
/* https://github.com/olikraus/u8g2/issues/474 */
static void u8x8_draw_1x2_subglyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding, uint8_t tile)
{
uint8_t i;
uint16_t t;
uint8_t buf[8];
uint8_t buf1[8];
uint8_t buf2[8];
u8x8_get_glyph_data(u8x8, encoding, buf, tile);
for( i = 0; i < 8; i ++ )
{
t = u8x8_upscale_byte(buf[i]);
buf1[i] = t >> 8;
buf2[i] = t & 255;
}
u8x8_DrawTile(u8x8, x, y, 1, buf2);
u8x8_DrawTile(u8x8, x, y+1, 1, buf1);
}
void u8x8_Draw1x2Glyph(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t encoding)
{
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
uint8_t tv = u8x8_pgm_read(u8x8->font+3); /* new 2019 format */
uint8_t xx, tile;
th += x;
tv *= 2;
tv += y;
tile = 0;
do
{
xx = x;
do
{
u8x8_draw_1x2_subglyph(u8x8, xx, y, encoding, tile);
tile++;
xx++;
} while( xx < th );
y+=2;
} while( y < tv );
}
/*
source: https://en.wikipedia.org/wiki/UTF-8
Bits from to bytes Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
7 U+0000 U+007F 1 0xxxxxxx
11 U+0080 U+07FF 2 110xxxxx 10xxxxxx
16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
/* reset the internal state machine */
void u8x8_utf8_init(u8x8_t *u8x8)
{
u8x8->utf8_state = 0; /* also reset during u8x8_SetupDefaults() */
}
uint16_t u8x8_ascii_next(U8X8_UNUSED u8x8_t *u8x8, uint8_t b)
{
if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */
return 0x0ffff; /* end of string detected*/
return b;
}
/*
pass a byte from an utf8 encoded string to the utf8 decoder state machine
returns
0x0fffe: no glyph, just continue
0x0ffff: end of string
anything else: The decoded encoding
*/
uint16_t u8x8_utf8_next(u8x8_t *u8x8, uint8_t b)
{
if ( b == 0 || b == '\n' ) /* '\n' terminates the string to support the string list procedures */
return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
if ( u8x8->utf8_state == 0 )
{
if ( b >= 0xfc ) /* 6 byte sequence */
{
u8x8->utf8_state = 5;
b &= 1;
}
else if ( b >= 0xf8 )
{
u8x8->utf8_state = 4;
b &= 3;
}
else if ( b >= 0xf0 )
{
u8x8->utf8_state = 3;
b &= 7;
}
else if ( b >= 0xe0 )
{
u8x8->utf8_state = 2;
b &= 15;
}
else if ( b >= 0xc0 )
{
u8x8->utf8_state = 1;
b &= 0x01f;
}
else
{
/* do nothing, just use the value as encoding */
return b;
}
u8x8->encoding = b;
return 0x0fffe;
}
else
{
u8x8->utf8_state--;
/* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
u8x8->encoding<<=6;
b &= 0x03f;
u8x8->encoding |= b;
if ( u8x8->utf8_state != 0 )
return 0x0fffe; /* nothing to do yet */
}
return u8x8->encoding;
}
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
static uint8_t u8x8_draw_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
uint16_t e;
uint8_t cnt = 0;
uint8_t th = u8x8_pgm_read(u8x8->font+2); /* new 2019 format */
u8x8_utf8_init(u8x8);
for(;;)
{
e = u8x8->next_cb(u8x8, (uint8_t)*s);
if ( e == 0x0ffff )
break;
s++;
if ( e != 0x0fffe )
{
u8x8_DrawGlyph(u8x8, x, y, e);
x+=th;
cnt++;
}
}
return cnt;
}
uint8_t u8x8_DrawString(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
u8x8->next_cb = u8x8_ascii_next;
return u8x8_draw_string(u8x8, x, y, s);
}
uint8_t u8x8_DrawUTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
u8x8->next_cb = u8x8_utf8_next;
return u8x8_draw_string(u8x8, x, y, s);
}
static uint8_t u8x8_draw_2x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
static uint8_t u8x8_draw_2x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
uint16_t e;
uint8_t cnt = 0;
u8x8_utf8_init(u8x8);
for(;;)
{
e = u8x8->next_cb(u8x8, (uint8_t)*s);
if ( e == 0x0ffff )
break;
s++;
if ( e != 0x0fffe )
{
u8x8_Draw2x2Glyph(u8x8, x, y, e);
x+=2;
cnt++;
}
}
return cnt;
}
uint8_t u8x8_Draw2x2String(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
u8x8->next_cb = u8x8_ascii_next;
return u8x8_draw_2x2_string(u8x8, x, y, s);
}
uint8_t u8x8_Draw2x2UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
u8x8->next_cb = u8x8_utf8_next;
return u8x8_draw_2x2_string(u8x8, x, y, s);
}
static uint8_t u8x8_draw_1x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s) U8X8_NOINLINE;
static uint8_t u8x8_draw_1x2_string(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
uint16_t e;
uint8_t cnt = 0;
u8x8_utf8_init(u8x8);
for(;;)
{
e = u8x8->next_cb(u8x8, (uint8_t)*s);
if ( e == 0x0ffff )
break;
s++;
if ( e != 0x0fffe )
{
u8x8_Draw1x2Glyph(u8x8, x, y, e);
x++;
cnt++;
}
}
return cnt;
}
uint8_t u8x8_Draw1x2String(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
u8x8->next_cb = u8x8_ascii_next;
return u8x8_draw_1x2_string(u8x8, x, y, s);
}
uint8_t u8x8_Draw1x2UTF8(u8x8_t *u8x8, uint8_t x, uint8_t y, const char *s)
{
u8x8->next_cb = u8x8_utf8_next;
return u8x8_draw_1x2_string(u8x8, x, y, s);
}
uint8_t u8x8_GetUTF8Len(u8x8_t *u8x8, const char *s)
{
uint16_t e;
uint8_t cnt = 0;
u8x8_utf8_init(u8x8);
for(;;)
{
e = u8x8_utf8_next(u8x8, *s);
if ( e == 0x0ffff )
break;
s++;
if ( e != 0x0fffe )
cnt++;
}
return cnt;
}

View File

@ -0,0 +1,666 @@
/*
u8x8_byte.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
uint8_t u8x8_byte_SetDC(u8x8_t *u8x8, uint8_t dc)
{
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SET_DC, dc, NULL);
}
uint8_t u8x8_byte_SendBytes(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
{
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_SEND, cnt, (void *)data);
}
uint8_t u8x8_byte_SendByte(u8x8_t *u8x8, uint8_t byte)
{
return u8x8_byte_SendBytes(u8x8, 1, &byte);
}
uint8_t u8x8_byte_StartTransfer(u8x8_t *u8x8)
{
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_START_TRANSFER, 0, NULL);
}
uint8_t u8x8_byte_EndTransfer(u8x8_t *u8x8)
{
return u8x8->byte_cb(u8x8, U8X8_MSG_BYTE_END_TRANSFER, 0, NULL);
}
/*=========================================*/
uint8_t u8x8_byte_empty(U8X8_UNUSED u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
case U8X8_MSG_BYTE_INIT:
case U8X8_MSG_BYTE_SET_DC:
case U8X8_MSG_BYTE_START_TRANSFER:
case U8X8_MSG_BYTE_END_TRANSFER:
break; /* do nothing */
}
return 1; /* always succeed */
}
/*=========================================*/
/*
Uses:
u8x8->display_info->sda_setup_time_ns
u8x8->display_info->sck_pulse_width_ns
u8x8->display_info->spi_mode
u8x8->display_info->chip_disable_level
u8x8->display_info->chip_enable_level
u8x8->display_info->post_chip_enable_wait_ns
u8x8->display_info->pre_chip_disable_wait_ns
Calls to GPIO and DELAY:
U8X8_MSG_DELAY_NANO
U8X8_MSG_GPIO_DC
U8X8_MSG_GPIO_CS
U8X8_MSG_GPIO_CLOCK
U8X8_MSG_GPIO_DATA
Handles:
U8X8_MSG_BYTE_INIT
U8X8_MSG_BYTE_SEND
U8X8_MSG_BYTE_SET_DC
U8X8_MSG_BYTE_START_TRANSFER
U8X8_MSG_BYTE_END_TRANSFER
*/
uint8_t u8x8_byte_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t i, b;
uint8_t *data;
uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
uint8_t not_takeover_edge = 1 - takeover_edge;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
b = *data;
data++;
arg_int--;
for( i = 0; i < 8; i++ )
{
if ( b & 128 )
u8x8_gpio_SetSPIData(u8x8, 1);
else
u8x8_gpio_SetSPIData(u8x8, 0);
b <<= 1;
u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
}
}
break;
case U8X8_MSG_BYTE_INIT:
/* disable chipselect */
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
/* no wait required here */
/* for SPI: setup correct level of the clock signal */
u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
break;
case U8X8_MSG_BYTE_SET_DC:
u8x8_gpio_SetDC(u8x8, arg_int);
break;
case U8X8_MSG_BYTE_START_TRANSFER:
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
break;
case U8X8_MSG_BYTE_END_TRANSFER:
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
break;
default:
return 0;
}
return 1;
}
/*=========================================*/
uint8_t u8x8_byte_8bit_6800mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t i, b;
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
b = *data;
data++;
arg_int--;
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
{
u8x8_gpio_call(u8x8, i, b&1);
b >>= 1;
}
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
}
break;
case U8X8_MSG_BYTE_INIT:
/* disable chipselect */
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
/* ensure that the enable signal is high */
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
break;
case U8X8_MSG_BYTE_SET_DC:
u8x8_gpio_SetDC(u8x8, arg_int);
break;
case U8X8_MSG_BYTE_START_TRANSFER:
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
break;
case U8X8_MSG_BYTE_END_TRANSFER:
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_byte_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t i, b;
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
b = *data;
data++;
arg_int--;
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
{
u8x8_gpio_call(u8x8, i, b&1);
b >>= 1;
}
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
}
break;
case U8X8_MSG_BYTE_INIT:
/* disable chipselect */
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
/* ensure that the enable signal is high */
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
break;
case U8X8_MSG_BYTE_SET_DC:
u8x8_gpio_SetDC(u8x8, arg_int);
break;
case U8X8_MSG_BYTE_START_TRANSFER:
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
break;
case U8X8_MSG_BYTE_END_TRANSFER:
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
break;
default:
return 0;
}
return 1;
}
/*=========================================*/
uint8_t u8x8_byte_3wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t i;
uint8_t *data;
uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
uint8_t not_takeover_edge = 1 - takeover_edge;
uint16_t b;
static uint8_t last_dc;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
b = *data;
if ( last_dc != 0 )
b |= 256;
data++;
arg_int--;
for( i = 0; i < 9; i++ )
{
if ( b & 256 )
u8x8_gpio_SetSPIData(u8x8, 1);
else
u8x8_gpio_SetSPIData(u8x8, 0);
b <<= 1;
u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
}
}
break;
case U8X8_MSG_BYTE_INIT:
/* disable chipselect */
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
/* no wait required here */
/* for SPI: setup correct level of the clock signal */
u8x8_gpio_SetSPIClock(u8x8, u8x8_GetSPIClockPhase(u8x8));
break;
case U8X8_MSG_BYTE_SET_DC:
last_dc = arg_int;
break;
case U8X8_MSG_BYTE_START_TRANSFER:
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
break;
case U8X8_MSG_BYTE_END_TRANSFER:
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
break;
default:
return 0;
}
return 1;
}
/*=========================================*/
void u8x8_byte_set_ks0108_cs(u8x8_t *u8x8, uint8_t arg)
{
u8x8_gpio_SetCS(u8x8, arg&1);
arg = arg >> 1;
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS1, arg&1);
arg = arg >> 1;
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS2, arg&1);
}
/* 6800 mode */
uint8_t u8x8_byte_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t i, b;
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
b = *data;
data++;
arg_int--;
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
{
u8x8_gpio_call(u8x8, i, b&1);
b >>= 1;
}
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 1);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns);
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
}
break;
case U8X8_MSG_BYTE_INIT:
/* disable chipselect */
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
/* ensure that the enable signal is low */
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
break;
case U8X8_MSG_BYTE_SET_DC:
u8x8_gpio_SetDC(u8x8, arg_int);
break;
case U8X8_MSG_BYTE_START_TRANSFER:
/* expects 3 bits in arg_int for the chip select lines */
u8x8_byte_set_ks0108_cs(u8x8, arg_int);
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
break;
case U8X8_MSG_BYTE_END_TRANSFER:
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
u8x8_byte_set_ks0108_cs(u8x8, arg_int);
break;
default:
return 0;
}
return 1;
}
/* sed1520 or sbn1661
U8X8_MSG_GPIO_E --> E1
U8X8_MSG_GPIO_CS --> E2
*/
uint8_t u8x8_byte_sed1520(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t i, b;
uint8_t *data;
static uint8_t enable_pin;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
b = *data;
data++;
arg_int--;
for( i = U8X8_MSG_GPIO_D0; i <= U8X8_MSG_GPIO_D7; i++ )
{
u8x8_gpio_call(u8x8, i, b&1);
b >>= 1;
}
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns);
u8x8_gpio_call(u8x8, enable_pin, 1);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 200); /* KS0108 requires 450 ns, use 200 here */
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); /* expect 250 here */
u8x8_gpio_call(u8x8, enable_pin, 0);
}
break;
case U8X8_MSG_BYTE_INIT:
/* disable chipselect */
u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
/* ensure that the enable signals are low */
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0);
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_CS, 0);
enable_pin = U8X8_MSG_GPIO_E;
break;
case U8X8_MSG_BYTE_SET_DC:
u8x8_gpio_SetDC(u8x8, arg_int);
break;
case U8X8_MSG_BYTE_START_TRANSFER:
/* cs lines are not supported for the SED1520/SBN1661 */
/* instead, this will select the E1 or E2 line */
enable_pin = U8X8_MSG_GPIO_E;
if ( arg_int != 0 )
enable_pin = U8X8_MSG_GPIO_CS;
break;
case U8X8_MSG_BYTE_END_TRANSFER:
break;
default:
return 0;
}
return 1;
}
/*=========================================*/
/*
software i2c,
ignores ACK response (which is anyway not provided by some displays)
also does not allow reading from the device
*/
static void i2c_delay(u8x8_t *u8x8) U8X8_NOINLINE;
static void i2c_delay(u8x8_t *u8x8)
{
//u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_10MICRO, u8x8->display_info->i2c_bus_clock_100kHz);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_I2C, u8x8->display_info->i2c_bus_clock_100kHz);
}
static void i2c_init(u8x8_t *u8x8)
{
u8x8_gpio_SetI2CClock(u8x8, 1);
u8x8_gpio_SetI2CData(u8x8, 1);
i2c_delay(u8x8);
}
/* actually, the scl line is not observed, so this procedure does not return a value */
static void i2c_read_scl_and_delay(u8x8_t *u8x8)
{
/* set as input (line will be high) */
u8x8_gpio_SetI2CClock(u8x8, 1);
i2c_delay(u8x8);
}
static void i2c_clear_scl(u8x8_t *u8x8)
{
u8x8_gpio_SetI2CClock(u8x8, 0);
}
static void i2c_read_sda(u8x8_t *u8x8)
{
/* set as input (line will be high) */
u8x8_gpio_SetI2CData(u8x8, 1);
}
static void i2c_clear_sda(u8x8_t *u8x8)
{
/* set open collector and drive low */
u8x8_gpio_SetI2CData(u8x8, 0);
}
static void i2c_start(u8x8_t *u8x8)
{
if ( u8x8->i2c_started != 0 )
{
/* if already started: do restart */
i2c_read_sda(u8x8); /* SDA = 1 */
i2c_delay(u8x8);
i2c_read_scl_and_delay(u8x8);
}
i2c_read_sda(u8x8);
/* send the start condition, both lines go from 1 to 0 */
i2c_clear_sda(u8x8);
i2c_delay(u8x8);
i2c_clear_scl(u8x8);
u8x8->i2c_started = 1;
}
static void i2c_stop(u8x8_t *u8x8)
{
/* set SDA to 0 */
i2c_clear_sda(u8x8);
i2c_delay(u8x8);
/* now release all lines */
i2c_read_scl_and_delay(u8x8);
/* set SDA to 1 */
i2c_read_sda(u8x8);
i2c_delay(u8x8);
u8x8->i2c_started = 0;
}
static void i2c_write_bit(u8x8_t *u8x8, uint8_t val)
{
if (val)
i2c_read_sda(u8x8);
else
i2c_clear_sda(u8x8);
i2c_delay(u8x8);
i2c_read_scl_and_delay(u8x8);
i2c_clear_scl(u8x8);
}
static void i2c_read_bit(u8x8_t *u8x8)
{
//uint8_t val;
/* do not drive SDA */
i2c_read_sda(u8x8);
i2c_delay(u8x8);
i2c_read_scl_and_delay(u8x8);
i2c_read_sda(u8x8);
i2c_delay(u8x8);
i2c_clear_scl(u8x8);
//return val;
}
static void i2c_write_byte(u8x8_t *u8x8, uint8_t b)
{
i2c_write_bit(u8x8, b & 128);
i2c_write_bit(u8x8, b & 64);
i2c_write_bit(u8x8, b & 32);
i2c_write_bit(u8x8, b & 16);
i2c_write_bit(u8x8, b & 8);
i2c_write_bit(u8x8, b & 4);
i2c_write_bit(u8x8, b & 2);
i2c_write_bit(u8x8, b & 1);
/* read ack from client */
/* 0: ack was given by client */
/* 1: nothing happend during ack cycle */
i2c_read_bit(u8x8);
}
uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
i2c_write_byte(u8x8, *data);
data++;
arg_int--;
}
break;
case U8X8_MSG_BYTE_INIT:
i2c_init(u8x8);
break;
case U8X8_MSG_BYTE_SET_DC:
break;
case U8X8_MSG_BYTE_START_TRANSFER:
i2c_start(u8x8);
i2c_write_byte(u8x8, u8x8_GetI2CAddress(u8x8));
//i2c_write_byte(u8x8, 0x078);
break;
case U8X8_MSG_BYTE_END_TRANSFER:
i2c_stop(u8x8);
break;
default:
return 0;
}
return 1;
}
/*=========================================*/
/* alternative i2c byte procedure */
#ifdef ALTERNATIVE_I2C_BYTE_PROCEDURE
void i2c_transfer(u8x8_t *u8x8, uint8_t adr, uint8_t cnt, uint8_t *data)
{
uint8_t i;
i2c_start(u8x8);
i2c_write_byte(u8x8, adr);
for( i = 0; i < cnt; i++ )
i2c_write_byte(u8x8, data[i]);
i2c_stop(u8x8);
}
uint8_t u8x8_byte_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
static uint8_t buffer[32]; /* u8g2/u8x8 will never send more than 32 bytes */
static uint8_t buf_idx;
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 )
{
buffer[buf_idx++] = *data;
data++;
arg_int--;
}
break;
case U8X8_MSG_BYTE_INIT:
i2c_init(u8x8); /* init i2c communication */
break;
case U8X8_MSG_BYTE_SET_DC:
/* ignored for i2c */
break;
case U8X8_MSG_BYTE_START_TRANSFER:
buf_idx = 0;
break;
case U8X8_MSG_BYTE_END_TRANSFER:
i2c_transfer(u8x8, u8x8_GetI2CAddress(u8x8), buf_idx, buffer);
break;
default:
return 0;
}
return 1;
}
#endif

View File

@ -0,0 +1,721 @@
/*
u8x8_cad.c
"command arg data" interface to the graphics controller
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The following sequence must be used for any data, which is set to the display:
uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8)
any of the following calls
uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd)
uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg)
uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8)
*/
/*
uint8_t u8x8_cad_template(u8x8_t *u8x8, uint8_t msg, uint16_t arg_int, void *arg_ptr)
{
uint8_t i;
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
u8x8_mcd_byte_SetDC(mcd->next, 1);
u8x8_mcd_byte_Send(mcd->next, arg_int);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_mcd_byte_SetDC(mcd->next, 1);
u8x8_mcd_byte_Send(mcd->next, arg_int);
break;
case U8X8_MSG_CAD_SEND_DATA:
u8x8_mcd_byte_SetDC(mcd->next, 0);
for( i = 0; i < 8; i++ )
u8x8_mcd_byte_Send(mcd->next, ((uint8_t *)arg_ptr)[i]);
break;
case U8X8_MSG_CAD_RESET:
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
case U8X8_MSG_CAD_START_TRANSFER:
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
case U8X8_MSG_CAD_END_TRANSFER:
return mcd->next->cb(mcd->next, msg, arg_int, arg_ptr);
default:
break;
}
return 1;
}
*/
#include "u8x8.h"
uint8_t u8x8_cad_SendCmd(u8x8_t *u8x8, uint8_t cmd)
{
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_CMD, cmd, NULL);
}
uint8_t u8x8_cad_SendArg(u8x8_t *u8x8, uint8_t arg)
{
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL);
}
uint8_t u8x8_cad_SendMultipleArg(u8x8_t *u8x8, uint8_t cnt, uint8_t arg)
{
while( cnt > 0 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_ARG, arg, NULL);
cnt--;
}
return 1;
}
uint8_t u8x8_cad_SendData(u8x8_t *u8x8, uint8_t cnt, uint8_t *data)
{
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, cnt, data);
}
uint8_t u8x8_cad_StartTransfer(u8x8_t *u8x8)
{
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
}
uint8_t u8x8_cad_EndTransfer(u8x8_t *u8x8)
{
return u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
}
/*
21 c send command c
22 a send arg a
23 d send data d
24 CS on
25 CS off
254 milli delay by milliseconds
255 end of sequence
*/
void u8x8_cad_SendSequence(u8x8_t *u8x8, uint8_t const *data)
{
uint8_t cmd;
uint8_t v;
for(;;)
{
cmd = *data;
data++;
switch( cmd )
{
case U8X8_MSG_CAD_SEND_CMD:
case U8X8_MSG_CAD_SEND_ARG:
v = *data;
u8x8->cad_cb(u8x8, cmd, v, NULL);
data++;
break;
case U8X8_MSG_CAD_SEND_DATA:
v = *data;
u8x8_cad_SendData(u8x8, 1, &v);
data++;
break;
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
u8x8->cad_cb(u8x8, cmd, 0, NULL);
break;
case 0x0fe:
v = *data;
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, v);
data++;
break;
default:
return;
}
}
}
uint8_t u8x8_cad_empty(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_DATA:
case U8X8_MSG_CAD_INIT:
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
default:
return 0;
}
return 1;
}
/*
convert to bytes by using
dc = 1 for commands and args and
dc = 0 for data
*/
uint8_t u8x8_cad_110(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
u8x8_byte_SetDC(u8x8, 1);
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_SetDC(u8x8, 1);
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_DATA:
u8x8_byte_SetDC(u8x8, 0);
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
//break;
/* fall through */
case U8X8_MSG_CAD_INIT:
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
default:
return 0;
}
return 1;
}
/*
convert to bytes by using
dc = 1 for commands and args and
dc = 0 for data
t6963
*/
uint8_t u8x8_cad_100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
u8x8_byte_SetDC(u8x8, 1);
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_SetDC(u8x8, 0);
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_DATA:
u8x8_byte_SetDC(u8x8, 0);
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
//break;
/* fall through */
case U8X8_MSG_CAD_INIT:
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
default:
return 0;
}
return 1;
}
/*
convert to bytes by using
dc = 0 for commands and args and
dc = 1 for data
*/
uint8_t u8x8_cad_001(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
u8x8_byte_SetDC(u8x8, 0);
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_SetDC(u8x8, 0);
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_DATA:
u8x8_byte_SetDC(u8x8, 1);
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
//break;
/* fall through */
case U8X8_MSG_CAD_INIT:
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
default:
return 0;
}
return 1;
}
/*
convert to bytes by using
dc = 0 for commands
dc = 1 for args and data
*/
uint8_t u8x8_cad_011(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
u8x8_byte_SetDC(u8x8, 0);
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_SetDC(u8x8, 1);
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_DATA:
u8x8_byte_SetDC(u8x8, 1);
//u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr);
//break;
/* fall through */
case U8X8_MSG_CAD_INIT:
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
default:
return 0;
}
return 1;
}
/* cad procedure for the ST7920 in SPI mode */
/* u8x8_byte_SetDC is not used */
uint8_t u8x8_cad_st7920_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t *data;
uint8_t b;
uint8_t i;
static uint8_t buf[16];
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
u8x8_byte_SendByte(u8x8, 0x0f8);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
u8x8_byte_SendByte(u8x8, arg_int & 0x0f0);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
u8x8_byte_SendByte(u8x8, arg_int << 4);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_SendByte(u8x8, 0x0f8);
u8x8_byte_SendByte(u8x8, arg_int & 0x0f0);
u8x8_byte_SendByte(u8x8, arg_int << 4);
break;
case U8X8_MSG_CAD_SEND_DATA:
u8x8_byte_SendByte(u8x8, 0x0fa);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
/* this loop should be optimized: multiple bytes should be sent */
/* u8x8_byte_SendBytes(u8x8, arg_int, arg_ptr); */
data = (uint8_t *)arg_ptr;
/* the following loop increases speed by 20% */
while( arg_int >= 8 )
{
i = 8;
ptr = buf;
do
{
b = *data++;
*ptr++= b & 0x0f0;
b <<= 4;
*ptr++= b;
i--;
} while( i > 0 );
arg_int -= 8;
u8x8_byte_SendBytes(u8x8, 16, buf);
}
while( arg_int > 0 )
{
b = *data;
u8x8_byte_SendByte(u8x8, b & 0x0f0);
u8x8_byte_SendByte(u8x8, b << 4);
data++;
arg_int--;
}
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, 1);
break;
case U8X8_MSG_CAD_INIT:
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
default:
return 0;
}
return 1;
}
/* cad procedure for the SSD13xx family in I2C mode */
/* this procedure is also used by the ST7588 */
/* u8x8_byte_SetDC is not used */
/* U8X8_MSG_BYTE_START_TRANSFER starts i2c transfer, U8X8_MSG_BYTE_END_TRANSFER stops transfer */
/* After transfer start, a full byte indicates command or data mode */
static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
{
u8x8_byte_StartTransfer(u8x8);
u8x8_byte_SendByte(u8x8, 0x040);
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, arg_ptr);
u8x8_byte_EndTransfer(u8x8);
}
/* classic version: will put a start/stop condition around each command and arg */
uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t *p;
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
case U8X8_MSG_CAD_SEND_ARG:
/* 7 Nov 2016: Can this be improved? */
//u8x8_byte_SetDC(u8x8, 0);
u8x8_byte_StartTransfer(u8x8);
//u8x8_byte_SendByte(u8x8, u8x8_GetI2CAddress(u8x8));
u8x8_byte_SendByte(u8x8, 0x000);
u8x8_byte_SendByte(u8x8, arg_int);
u8x8_byte_EndTransfer(u8x8);
break;
case U8X8_MSG_CAD_SEND_DATA:
//u8x8_byte_SetDC(u8x8, 1);
/* the FeatherWing OLED with the 32u4 transfer of long byte */
/* streams was not possible. This is broken down to */
/* smaller streams, 32 seems to be the limit... */
/* I guess this is related to the size of the Wire buffers in Arduino */
/* Unfortunately, this can not be handled in the byte level drivers, */
/* so this is done here. Even further, only 24 bytes will be sent, */
/* because there will be another byte (DC) required during the transfer */
p = arg_ptr;
while( arg_int > 24 )
{
u8x8_i2c_data_transfer(u8x8, 24, p);
arg_int-=24;
p+=24;
}
u8x8_i2c_data_transfer(u8x8, arg_int, p);
break;
case U8X8_MSG_CAD_INIT:
/* apply default i2c adr if required so that the start transfer msg can use this */
if ( u8x8->i2c_address == 255 )
u8x8->i2c_address = 0x078;
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
/* cad transfer commands are ignored */
break;
default:
return 0;
}
return 1;
}
/* fast version with reduced data start/stops, issue 735 */
uint8_t u8x8_cad_ssd13xx_fast_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
static uint8_t in_transfer = 0;
uint8_t *p;
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
/* improved version, takeover from ld7032 */
/* assumes, that the args of a command is not longer than 31 bytes */
/* speed improvement is about 4% compared to the classic version */
if ( in_transfer != 0 )
u8x8_byte_EndTransfer(u8x8);
u8x8_byte_StartTransfer(u8x8);
u8x8_byte_SendByte(u8x8, 0x000); /* cmd byte for ssd13xx controller */
u8x8_byte_SendByte(u8x8, arg_int);
in_transfer = 1;
/* lightning version: can replace the improved version from above */
/* the drawback of the lightning version is this: The complete init sequence */
/* must fit into the 32 byte Arduino Wire buffer, wbich might not always be the case */
/* speed improvement is about 6% compared to the classic version */
// if ( in_transfer == 0 )
// {
// u8x8_byte_StartTransfer(u8x8);
// u8x8_byte_SendByte(u8x8, 0x000); /* cmd byte for ssd13xx controller */
// in_transfer = 1;
// }
//u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_DATA:
if ( in_transfer != 0 )
u8x8_byte_EndTransfer(u8x8);
/* the FeatherWing OLED with the 32u4 transfer of long byte */
/* streams was not possible. This is broken down to */
/* smaller streams, 32 seems to be the limit... */
/* I guess this is related to the size of the Wire buffers in Arduino */
/* Unfortunately, this can not be handled in the byte level drivers, */
/* so this is done here. Even further, only 24 bytes will be sent, */
/* because there will be another byte (DC) required during the transfer */
p = arg_ptr;
while( arg_int > 24 )
{
u8x8_i2c_data_transfer(u8x8, 24, p);
arg_int-=24;
p+=24;
}
u8x8_i2c_data_transfer(u8x8, arg_int, p);
in_transfer = 0;
break;
case U8X8_MSG_CAD_INIT:
/* apply default i2c adr if required so that the start transfer msg can use this */
if ( u8x8->i2c_address == 255 )
u8x8->i2c_address = 0x078;
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
case U8X8_MSG_CAD_START_TRANSFER:
in_transfer = 0;
break;
case U8X8_MSG_CAD_END_TRANSFER:
if ( in_transfer != 0 )
u8x8_byte_EndTransfer(u8x8);
in_transfer = 0;
break;
default:
return 0;
}
return 1;
}
/* the st75256 i2c driver is a copy of the ssd13xx driver, but with arg=1 */
/* modified from cad001 (ssd13xx) to cad011 */
uint8_t u8x8_cad_st75256_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t *p;
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
u8x8_byte_StartTransfer(u8x8);
u8x8_byte_SendByte(u8x8, 0x000);
u8x8_byte_SendByte(u8x8, arg_int);
u8x8_byte_EndTransfer(u8x8);
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_StartTransfer(u8x8);
u8x8_byte_SendByte(u8x8, 0x040);
u8x8_byte_SendByte(u8x8, arg_int);
u8x8_byte_EndTransfer(u8x8);
break;
case U8X8_MSG_CAD_SEND_DATA:
/* see ssd13xx driver */
p = arg_ptr;
while( arg_int > 24 )
{
u8x8_i2c_data_transfer(u8x8, 24, p);
arg_int-=24;
p+=24;
}
u8x8_i2c_data_transfer(u8x8, arg_int, p);
break;
case U8X8_MSG_CAD_INIT:
/* apply default i2c adr if required so that the start transfer msg can use this */
if ( u8x8->i2c_address == 255 )
u8x8->i2c_address = 0x078; /* ST75256, often this is 0x07e */
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
case U8X8_MSG_CAD_START_TRANSFER:
case U8X8_MSG_CAD_END_TRANSFER:
/* cad transfer commands are ignored */
break;
default:
return 0;
}
return 1;
}
/* cad i2c procedure for the ld7032 controller */
uint8_t u8x8_cad_ld7032_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
static uint8_t in_transfer = 0;
uint8_t *p;
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
if ( in_transfer != 0 )
u8x8_byte_EndTransfer(u8x8);
u8x8_byte_StartTransfer(u8x8);
u8x8_byte_SendByte(u8x8, arg_int);
in_transfer = 1;
break;
case U8X8_MSG_CAD_SEND_ARG:
u8x8_byte_SendByte(u8x8, arg_int);
break;
case U8X8_MSG_CAD_SEND_DATA:
//u8x8_byte_SetDC(u8x8, 1);
/* the FeatherWing OLED with the 32u4 transfer of long byte */
/* streams was not possible. This is broken down to */
/* smaller streams, 32 seems to be the limit... */
/* I guess this is related to the size of the Wire buffers in Arduino */
/* Unfortunately, this can not be handled in the byte level drivers, */
/* so this is done here. Even further, only 24 bytes will be sent, */
/* because there will be another byte (DC) required during the transfer */
p = arg_ptr;
while( arg_int > 24 )
{
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
arg_int-=24;
p+=24;
u8x8_byte_EndTransfer(u8x8);
u8x8_byte_StartTransfer(u8x8);
u8x8_byte_SendByte(u8x8, 0x08); /* data write for LD7032 */
}
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
break;
case U8X8_MSG_CAD_INIT:
/* apply default i2c adr if required so that the start transfer msg can use this */
if ( u8x8->i2c_address == 255 )
u8x8->i2c_address = 0x060;
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
case U8X8_MSG_CAD_START_TRANSFER:
in_transfer = 0;
break;
case U8X8_MSG_CAD_END_TRANSFER:
if ( in_transfer != 0 )
u8x8_byte_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/* cad procedure for the UC16xx family in I2C mode */
/* u8x8_byte_SetDC is not used */
/* DC bit is encoded into the adr byte */
uint8_t u8x8_cad_uc16xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
static uint8_t in_transfer = 0;
static uint8_t is_data = 0;
uint8_t *p;
switch(msg)
{
case U8X8_MSG_CAD_SEND_CMD:
case U8X8_MSG_CAD_SEND_ARG:
if ( in_transfer != 0 )
{
if ( is_data != 0 )
{
/* transfer mode is active, but data transfer */
u8x8_byte_EndTransfer(u8x8);
/* clear the lowest two bits of the adr */
u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
u8x8_byte_StartTransfer(u8x8);
}
}
else
{
/* clear the lowest two bits of the adr */
u8x8_SetI2CAddress( u8x8, u8x8_GetI2CAddress(u8x8)&0x0fc );
u8x8_byte_StartTransfer(u8x8);
}
u8x8_byte_SendByte(u8x8, arg_int);
in_transfer = 1;
break;
case U8X8_MSG_CAD_SEND_DATA:
if ( in_transfer != 0 )
{
if ( is_data == 0 )
{
/* transfer mode is active, but data transfer */
u8x8_byte_EndTransfer(u8x8);
/* clear the lowest two bits of the adr */
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
u8x8_byte_StartTransfer(u8x8);
}
}
else
{
/* clear the lowest two bits of the adr */
u8x8_SetI2CAddress( u8x8, (u8x8_GetI2CAddress(u8x8)&0x0fc)|2 );
u8x8_byte_StartTransfer(u8x8);
}
in_transfer = 1;
p = arg_ptr;
while( arg_int > 24 )
{
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
arg_int-=24;
p+=24;
u8x8_byte_EndTransfer(u8x8);
u8x8_byte_StartTransfer(u8x8);
}
u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, arg_int, p);
break;
case U8X8_MSG_CAD_INIT:
/* apply default i2c adr if required so that the start transfer msg can use this */
if ( u8x8->i2c_address == 255 )
u8x8->i2c_address = 0x070;
return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
case U8X8_MSG_CAD_START_TRANSFER:
in_transfer = 0;
/* actual start is delayed, because we do not whether this is data or cmd transfer */
break;
case U8X8_MSG_CAD_END_TRANSFER:
if ( in_transfer != 0 )
u8x8_byte_EndTransfer(u8x8);
in_transfer = 0;
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,182 @@
/*
u8x8_d_a2printer.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Use DC2 bitmap command of the A2 Micro panel termal printer
double stroke
*/
#include "u8x8.h"
#define LINE_MIN_DELAY_MS 15
/* higher values improve quality */
/* however if the value is too high (>=5) then form feed does not work any more */
#define LINE_EXTRA_8PIXEL_DELAY_MS 3
/* this must be a power of two and between 1 and 8 */
/* best quality only with 1 */
#define NO_OF_LINES_TO_SEND_WITHOUT_DELAY 1
/* calculates the delay, based on the number of black pixel */
/* actually only "none-zero" bytes are calculated which is, of course not so accurate, but should be good enough */
uint16_t get_delay_in_milliseconds(uint8_t cnt, uint8_t *data)
{
uint8_t i;
uint16_t time = LINE_MIN_DELAY_MS;
for ( i = 0; i < cnt; i++ )
if ( data[i] != 0 )
time += LINE_EXTRA_8PIXEL_DELAY_MS;
return time;
}
uint8_t u8x8_d_a2printer_common(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
{
uint8_t c, i, j;
uint8_t *ptr;
uint16_t delay_in_milliseconds;
switch(msg)
{
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
/*
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
// no setup required
// u8x8_cad_SendSequence(u8x8, u8x8_d_a2printer_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
// no powersave
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 27); /* ESC */
u8x8_cad_SendCmd(u8x8, 55 ); /* parameter command */
/* increasing the "max printing dots" requires a good power supply, but LINE_EXTRA_8PIXEL_DELAY_MS could be reduced then */
u8x8_cad_SendCmd(u8x8, 0); /* Max printing dots,Unit(8dots),Default:7(64 dots) 8*(x+1) ... lower values improve, probably my current supply is not sufficient */
u8x8_cad_SendCmd(u8x8, 200); /* 3-255 Heating time,Unit(10us),Default:80(800us) */
u8x8_cad_SendCmd(u8x8, 2); /* 0-255 Heating interval,Unit(10us),Default:2(20us) ... does not have much influence */
//c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
c = u8x8->display_info->tile_width;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
u8x8_cad_SendCmd(u8x8, 18); /* DC2 */
u8x8_cad_SendCmd(u8x8, 42 ); /* * */
u8x8_cad_SendCmd(u8x8, 8 ); /* height */
u8x8_cad_SendCmd(u8x8, c ); /* c, u8x8->display_info->tile_width */
for( j = 0; j < 8 / NO_OF_LINES_TO_SEND_WITHOUT_DELAY; j ++ )
{
delay_in_milliseconds = 0;
for( i = 0; i < NO_OF_LINES_TO_SEND_WITHOUT_DELAY; i++ )
{
u8x8_cad_SendData(u8x8, c, ptr); /* c, note: SendData can not handle more than 255 bytes, send one line of data */
delay_in_milliseconds += get_delay_in_milliseconds(c, ptr);
ptr += c;
}
while( delay_in_milliseconds > 200 )
{
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_MILLI, 200, NULL);
delay_in_milliseconds -= 200;
}
u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_MILLI, delay_in_milliseconds, NULL);
}
/* set parameters back to their default values */
u8x8_cad_SendCmd(u8x8, 27); /* ESC */
u8x8_cad_SendCmd(u8x8, 55 ); /* parameter command */
u8x8_cad_SendCmd(u8x8, 7); /* Max printing dots,Unit(8dots),Default:7(64 dots) 8*(x+1)*/
u8x8_cad_SendCmd(u8x8, 80); /* 3-255 Heating time,Unit(10us),Default:80(800us) */
u8x8_cad_SendCmd(u8x8, 2); /* 0-255 Heating interval,Unit(10us),Default:2(20us)*/
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_a2printer_384x240_display_info =
{
/* most of the settings are not required, because this is a serial RS232 printer */
/* chip_enable_level = */ 1,
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 5,
/* pre_chip_disable_wait_ns = */ 5,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140,
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* old: sck_takeover_edge, new: active high (bit 1), rising edge (bit 0) */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30,
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 48,
/* tile_hight = */ 30,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 384,
/* pixel_height = */ 240
};
uint8_t u8x8_d_a2printer_384x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_a2printer_384x240_display_info);
break;
default:
return u8x8_d_a2printer_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}

View File

@ -0,0 +1,552 @@
/*
u8x8_d_il3820_296x128.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
il3820: 200x300x1
command
0x22: assign actions
0x20: execute actions
action for command 0x022 are (more or less guessed)
bit 7: Enable Clock
bit 6: Enable Charge Pump
bit 5: Load Temparture Value (???)
bit 4: Load LUT (???)
bit 3: Initial Display (???)
bit 2: Pattern Display --> Requires about 945ms with the LUT from below
bit 1: Disable Charge Pump
bit 0: Disable Clock
Disable Charge Pump and Clock require about 10ms
Enable Charge Pump and Clock require about 100 to 300ms
Notes:
- Introduced a refresh display message, which copies RAM to display
- Charge pump is always enabled. Charge pump can be enabled/disabled via power save message
- U8x8 will not really work because of the two buffers in the SSD1606, however U8g2 should be ok.
LUT for the 296x128 device (IL3820)
LUT (cmd: 0x032 has 30 bytes)
section 6.8 of the datasheet mentions 256 bits = 32 bytes for the LUT
chapter 7 tells 30 bytes
according to section 6.8:
20 bytes waveform
10 bytes timing
1 byte named as VSH/VSL
1 empty byte
according to the command table, the lut has 240 bits (=30 bytes * 8 bits)
LUT / Refresh time
total_refresh_time = (refresh_lines + dummy_lines*2)*TGate*TS_Sum/f_OSC
f_OSC=1MHz (according to the datasheets)
refreh_lines = 296 (for the waveshare display, 0x045 cmd)
dummy_lines = 22 (for the upcoming u8g2 code, 0x03a cmd)
TGate = 62 (POR default, 0x03b cmd)
TS_Sum: Sum of all TS entries of the second part of the LUT
f_OSC: 1MHz according to the datasheet.
so we have
total_refresh_time = 21080*TS_Sum/1000000 = 21ms * TS_Sum
This file includes two devices:
u8x8_d_il3820_296x128 --> includes LUT which is probably from the WaveShare 2.9 Vendor
u8x8_d_il3820_v2_296x128 --> includes LUT which was optimized for faster speed and lesser flicker
*/
/* Waveform part of the LUT (20 bytes) */
/* bit 7/6: 1 - 1 transition */
/* bit 5/4: 1 - 0 transition */
/* bit 3/2: 0 - 1 transition */
/* bit 1/0: 0 - 0 transition */
/* 00 VSS */
/* 01 VSH */
/* 10 VSL */
/* 11 NA */
#include "u8x8.h"
/*=================================================*/
/* common code for all devices */
static const uint8_t u8x8_d_il3820_296x128_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x22, 0xc0), /* enable clock and charge pump */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(200), /* according to my measures it may take up to 150ms */
U8X8_DLY(100), /* but it might take longer */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_il3820_296x128_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
/* disable clock and charge pump only, deep sleep is not entered, because we will loose RAM content */
U8X8_CA(0x22, 0x02), /* only disable charge pump, HW reset seems to be required if the clock is disabled */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(20),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
// static const uint8_t u8x8_d_il3820_296x128_flip0_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
// static const uint8_t u8x8_d_il3820_296x128_flip1_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
static const u8x8_display_info_t u8x8_il3820_296x128_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 120,
/* pre_chip_disable_wait_ns = */ 60,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 50, /* IL3820 */
/* sck_pulse_width_ns = */ 125, /* IL3820: 125ns, clock cycle = 250ns */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150,
/* tile_width = */ 37, /* 37*8 = 296 */
/* tile_hight = */ 16, /* 16*8 = 128 */
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 296,
/* pixel_height = */ 128
};
static uint8_t *u8x8_convert_tile_for_il3820(uint8_t *t)
{
uint8_t i;
static uint8_t buf[8];
uint8_t *pbuf = buf;
for( i = 0; i < 8; i++ )
{
*pbuf++ = ~(*t++);
}
return buf;
}
static void u8x8_d_il3820_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
static void u8x8_d_il3820_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
{
uint16_t x;
uint8_t c, page;
uint8_t *ptr;
u8x8_cad_StartTransfer(u8x8);
page = u8x8->display_info->tile_height;
page --;
page -= (((u8x8_tile_t *)arg_ptr)->y_pos);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
//u8x8_cad_SendCmd(u8x8, 0x011 ); /* cursor increment mode */
//u8x8_cad_SendArg(u8x8, 7);
u8x8_cad_SendCmd(u8x8, 0x04f ); /* set cursor column */
u8x8_cad_SendArg(u8x8, x&255);
u8x8_cad_SendArg(u8x8, x>>8);
u8x8_cad_SendCmd(u8x8, 0x04e ); /* set cursor row */
u8x8_cad_SendArg(u8x8, page);
u8x8_cad_SendCmd(u8x8, 0x024 );
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, 8, u8x8_convert_tile_for_il3820(ptr));
ptr += 8;
x += 8;
c--;
} while( c > 0 );
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
}
static const uint8_t u8x8_d_il3820_exec_1000dly_seq[] = {
// assumes, that the start transfer has happend
U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static void u8x8_d_il3820_first_init(u8x8_t *u8x8)
{
u8x8_ClearDisplay(u8x8);
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x032); // program update sequence
u8x8_cad_SendMultipleArg(u8x8, 8, 0x055); // all black
u8x8_cad_SendMultipleArg(u8x8, 12, 0x0aa); // all white
u8x8_cad_SendMultipleArg(u8x8, 10, 0x022); // 830ms
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_exec_1000dly_seq);
}
#ifdef OBSOLETE
static void u8x8_d_il3820_second_init(u8x8_t *u8x8)
{
u8x8_ClearDisplay(u8x8);
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x032); // program update sequence
u8x8_cad_SendMultipleArg(u8x8, 20, 0x000); // do nothing
u8x8_cad_SendMultipleArg(u8x8, 10, 0x011); // 414ms dly
/* reuse sequence from above, ok some time is wasted here, */
/* delay could be lesser */
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_exec_1000dly_seq);
}
#endif
/*=================================================*/
/* first version, LUT from WaveShare */
/* http://www.waveshare.com/wiki/File:2.9inch_e-Paper_Module_code.7z */
static const uint8_t u8x8_d_il3820_296x128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: Disable */
U8X8_C(0x01),
U8X8_A(295 % 256), U8X8_A(295/256), U8X8_A(0),
U8X8_CA(0x03, 0x00), /* Gate Driving voltage: 15V (lowest value)*/
U8X8_CA(0x04, 0x0a), /* Source Driving voltage: 15V (mid value and POR)*/
//U8X8_CA(0x22, 0xc0), /* display update seq. option: enable clk, enable CP, .... todo: this is never activated */
//U8X8_CA(0x0b, 7), /* Set Delay of gate and source non overlap period, POR = 7 */
U8X8_CA(0x2c, 0xa8), /* write vcom value*/
U8X8_CA(0x3a, 0x16), /* dummy lines POR=22 (0x016) */
U8X8_CA(0x3b, 0x08), /* gate time POR=0x08*/
U8X8_CA(0x3c, 0x33), /* select boarder waveform */
//U8X8_CA(0x22, 0xc4), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
U8X8_CA(0x11, 0x07), /* Define data entry mode, x&y inc, x first*/
U8X8_CAA(0x44, 0, 29), /* RAM x start & end, 32*4=128 */
U8X8_CAAAA(0x45, 0, 0, 295&255, 295>>8), /* RAM y start & end, 0..295 */
//U8X8_CA(0x4e, 0), /* set x pos, 0..29? */
//U8X8_CAA(0x4f, 0, 0), /* set y pos, 0...320??? */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_il3820_to_display_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
/*
0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
measured 1582 ms
*/
U8X8_C(0x32), /* write LUT register*/
/* original values */
U8X8_A(0x50),
U8X8_A(0xaa),
U8X8_A(0x55),
U8X8_A(0xaa),
U8X8_A(0x11),
U8X8_A(0x11),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
/* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */
U8X8_A(0xff),
U8X8_A(0xff),
U8X8_A(0x3f),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display, assumes clk and charge pump are enabled */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(250), /* delay for 1620ms. The current sequence takes 1582ms */
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(120),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_il3820_296x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_il3820_296x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_init_seq);
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave0_seq);
u8x8_d_il3820_first_init(u8x8);
/* usually the DISPLAY_INIT message leaves the display in power save state */
/* however this is not done for e-paper devices, see: */
/* https://github.com/olikraus/u8g2/wiki/internal#powersave-mode */
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_d_il3820_draw_tile(u8x8, arg_int, arg_ptr);
break;
case U8X8_MSG_DISPLAY_REFRESH:
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_to_display_seq);
break;
default:
return 0;
}
return 1;
}
/*=================================================*/
/* second version for the IL3820 display */
/* http://www.waveshare.com/wiki/File:2.9inch_e-Paper_Module_code.7z */
static const uint8_t u8x8_d_il3820_v2_296x128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: POR: Normal mode */
U8X8_C(0x01),
U8X8_A(295 % 256), U8X8_A(295/256), U8X8_A(0),
/* the driving voltagesmust not be that high, in order to aviod level change after */
/* some seconds (which happens with 0xea */
U8X8_CA(0x03, 0x75), /* Gate Driving voltage: +/-15V =0x00 POR (+22/-20V) = 0x0ea*/
U8X8_CA(0x04, 0x0a), /* Source Driving voltage: (POR=0x0a=15V), max=0x0e*/
U8X8_CA(0x0b, 7), /* Set Delay of gate and source non overlap period, POR = 7 */
U8X8_CA(0x2c, 0xa8), /* write vcom value*/
U8X8_CA(0x3a, 0x16), /* dummy lines POR=22 (0x016) */
U8X8_CA(0x3b, 0x08), /* gate time POR=0x08*/
U8X8_CA(0x3c, 0x33), /* select boarder waveform */
U8X8_CA(0x11, 0x07), /* Define data entry mode, x&y inc, x first*/
U8X8_CAA(0x44, 0, 29), /* RAM x start & end, 32*4=128 */
U8X8_CAAAA(0x45, 0, 0, 295&255, 295>>8), /* RAM y start & end, 0..295 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_il3820_v2_to_display_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
/*
0xaa, 0x09, 0x09, 0x19, 0x19,
0x11, 0x11, 0x11, 0x11, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x77, 0x77, 0x77, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00
measured 1240 ms
*/
U8X8_C(0x32), /* write LUT register*/
/* https://github.com/olikraus/u8g2/issues/347 */
U8X8_A(0xaa),
U8X8_A(0x09),
U8X8_A(0x09),
U8X8_A(0x19),
U8X8_A(0x19),
U8X8_A(0x11),
U8X8_A(0x11),
U8X8_A(0x11),
U8X8_A(0x11),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
/* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */
U8X8_A(0x75),
U8X8_A(0x77),
U8X8_A(0x77),
U8X8_A(0x77),
U8X8_A(0x07),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(250), /* delay for 1400ms. The current sequence takes 1240ms, it was reported, that longer delays are better */
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(150), /* extended, #318 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_il3820_v2_296x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_il3820_296x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_v2_296x128_init_seq);
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave0_seq);
u8x8_d_il3820_first_init(u8x8);
/* u8x8_d_il3820_second_init(u8x8); */ /* not required, u8g2.begin() will also clear the display once more */
/* usually the DISPLAY_INIT message leaves the display in power save state */
/* however this is not done for e-paper devices, see: */
/* https://github.com/olikraus/u8g2/wiki/internal#powersave-mode */
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_296x128_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_d_il3820_draw_tile(u8x8, arg_int, arg_ptr);
break;
case U8X8_MSG_DISPLAY_REFRESH:
u8x8_cad_SendSequence(u8x8, u8x8_d_il3820_v2_to_display_seq);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,200 @@
/*
u8x8_d_ist3020.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ist3020_erc19264_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a4), /* all pixel off, issue 142 */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ist3020_erc19264_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ist3020_erc19264_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ist3020_erc19264_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_ist3020_erc19264_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 150, /* IST3020 datasheet, page 56 */
/* pre_chip_disable_wait_ns = */ 150, /* IST3020 datasheet, page 56 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 1,
/* sda_setup_time_ns = */ 100, /* IST3020 datasheet, page 56 */
/* sck_pulse_width_ns = */ 100, /* IST3020 datasheet, page 56 */
/* sck_clock_hz = */ 4000000UL, /* */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40, /* IST3020 datasheet, page 54 */
/* write_pulse_width_ns = */ 60, /* IST3020 datasheet, page 54 */
/* tile_width = */ 24, /* width of 24*8=192 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 64,
/* pixel_width = */ 192,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_ist3020_erc19264_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_C(0x0ab), /* build in osc on, used in ER code, but not mentioned in data sheet */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x0a0), /* ADC set to reverse */
U8X8_C(0x0c8), /* common output mode */
// Flipmode
//U8X8_C(0x0a0), /* ADC set to reverse */
//U8X8_C(0x0c8), /* common output mode */
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
U8X8_C(0x0a3), /* FIX: LCD bias 1/7, old value was 1/9 (0x0a2) */
U8X8_C(0x028|4), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|6), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|7), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x020), /* v0 voltage resistor ratio */
U8X8_CA(0x081, 0x019), /* set contrast, contrast value (from ER code: 45) */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ist3020_erc19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ist3020_erc19264_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ist3020_erc19264_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,344 @@
/*
u8x8_d_ks0108.c
The classic 5V LCD
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ks0108_init_seq[] = {
U8X8_C(0x0c0), /* satart at the top */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ks0108_powersave0_seq[] = {
U8X8_C(0x03f), /* display on */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ks0108_powersave1_seq[] = {
U8X8_C(0x03e), /* display off */
U8X8_END() /* end of sequence */
};
struct u8x8_ks0108_vars
{
uint8_t *ptr;
uint8_t x;
uint8_t c;
uint8_t arg_int;
};
static void u8x8_ks0108_out(u8x8_t *u8x8, struct u8x8_ks0108_vars *v, void *arg_ptr)
{
uint8_t cnt;
u8x8_cad_SendCmd(u8x8, 0x040 | ((v->x << 3) & 63) );
u8x8_cad_SendCmd(u8x8, 0x0b8 | (((u8x8_tile_t *)arg_ptr)->y_pos));
while( v->arg_int > 0 )
{
/* calculate tiles to next boundary (end or chip limit) */
cnt = v->x;
cnt += 8;
cnt &= 0x0f8;
cnt -= v->x;
if ( cnt > v->c )
cnt = v->c;
/* of cours we still could use cnt=1 here... */
/* but setting cnt to 1 is not very efficient */
//cnt = 1;
v->x +=cnt;
v->c-=cnt;
cnt<<=3;
u8x8_cad_SendData(u8x8, cnt, v->ptr); /* note: SendData can not handle more than 255 bytes */
v->ptr += cnt;
if ( v->c == 0 )
{
v->ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
v->c = ((u8x8_tile_t *)arg_ptr)->cnt;
v->arg_int--;
}
if ( ((v->x) & 7) == 0 )
break;
}
}
static const u8x8_display_info_t u8x8_ks0108_128x64_display_info =
{
/* chip_enable_level = */ 0, /* KS0108: Not used */
/* chip_disable_level = */ 1, /* KS0108: Not used */
/* post_chip_enable_wait_ns = */ 100,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6, /* could be faster for the KS0108 */
/* sda_setup_time_ns = */ 12,
/* sck_pulse_width_ns = */ 75, /* KS0108: Not used */
/* sck_clock_hz = */ 4000000UL, /* KS0108: Not used */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4, /* KS0108: Not used */
/* data_setup_time_ns = */ 200,
/* write_pulse_width_ns = */ 250, /* KS0108: actially 450 ns, but additional 200 ns are added by the byte transfer function */
/* tile_width = */ 16, /* width of 16*8=128 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
uint8_t u8x8_d_ks0108_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
struct u8x8_ks0108_vars v;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ks0108_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 2, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 2, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
}
else
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 2, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
}
break;
// The KS0108 can not mirror the cols and rows, use U8g2 for rotation
// case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
// break;
// The KS0108 has no internal contrast command
// case U8X8_MSG_DISPLAY_SET_CONTRAST:
// break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
v.ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
v.x = ((u8x8_tile_t *)arg_ptr)->x_pos;
v.c = ((u8x8_tile_t *)arg_ptr)->cnt;
v.arg_int = arg_int;
if ( v.x < 8 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
u8x8_ks0108_out(u8x8, &v, arg_ptr);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
}
if ( v.x < 16 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 2, NULL);
u8x8_ks0108_out(u8x8, &v, arg_ptr);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
}
//if ( v.x < 24 )
//{
//u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 4, NULL);
//u8x8_ks0108_out(u8x8, &v, arg_ptr);
//u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
//}
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ks0108_192x64_display_info =
{
/* chip_enable_level = */ 0, /* KS0108: Not used */
/* chip_disable_level = */ 1, /* KS0108: Not used */
/* post_chip_enable_wait_ns = */ 100,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6, /* could be faster for the KS0108 */
/* sda_setup_time_ns = */ 12,
/* sck_pulse_width_ns = */ 75, /* KS0108: Not used */
/* sck_clock_hz = */ 4000000UL, /* KS0108: Not used */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4, /* KS0108: Not used */
/* data_setup_time_ns = */ 200,
/* write_pulse_width_ns = */ 250, /* KS0108: actially 450 ns, but additional 200 ns are added by the byte transfer function */
/* tile_width = */ 24, /* width of 24*8=192 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 192,
/* pixel_height = */ 64
};
/* east rising (buydisplay.com) ERM19264 */
/* left: 011, middle: 101, right: 110, no chip select: 111 */
uint8_t u8x8_d_ks0108_erm19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
struct u8x8_ks0108_vars v;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ks0108_192x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 3, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 5, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 6, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 3, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 5, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 6, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave0_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
}
else
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 3, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 5, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 6, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
}
break;
// The KS0108 can not mirror the cols and rows, use U8g2 for rotation
// case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
// break;
// The KS0108 has no internal contrast command
// case U8X8_MSG_DISPLAY_SET_CONTRAST:
// break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
v.ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
v.x = ((u8x8_tile_t *)arg_ptr)->x_pos;
v.c = ((u8x8_tile_t *)arg_ptr)->cnt;
v.arg_int = arg_int;
/*
3-bit CS value:
In u8x8_byte_set_ks0108_cs(u8x8_t *u8x8, uint8_t arg) the lowest
bit is assigned to CS and highest bit if the 3-bit value to CS2
CS: left part of the display --> 6
CS1: middle part --> 5
CS2: right part of the display --> 3
Reference: https://github.com/olikraus/u8g2/issues/631
*/
if ( v.x < 8 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 6, NULL); // 3-->6, issue 631
u8x8_ks0108_out(u8x8, &v, arg_ptr);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
}
if ( v.x < 16 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 5, NULL);
u8x8_ks0108_out(u8x8, &v, arg_ptr);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
}
if ( v.x < 24 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 3, NULL); // 6-->3, // issue 631
u8x8_ks0108_out(u8x8, &v, arg_ptr);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 7, NULL);
}
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,470 @@
/*
u8x8_d_lc7981.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* no powersave mode for the LC7981 */
// static const uint8_t u8x8_d_lc7981_powersave0_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
// static const uint8_t u8x8_d_lc7981_powersave1_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
/* no hardware flip for the LC7981 */
// static const uint8_t u8x8_d_lc7981_flip0_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
// static const uint8_t u8x8_d_lc7981_flip1_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
/* http://graphics.stanford.edu/~seander/bithacks.html */
static uint8_t reverse_byte(uint8_t v)
{
// if ( v != 0 && v != 255 ) does not help much
{
// swap odd and even bits
v = ((v >> 1) & 0x055) | ((v & 0x055) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x033) | ((v & 0x033) << 2);
// swap nibbles ...
v = ((v >> 4) & 0x00F) | ((v & 0x00F) << 4);
}
return v;
}
static uint8_t u8x8_d_lc7981_common(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
{
uint8_t c, i, j;
uint16_t y;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y*=8;
y*= u8x8->display_info->tile_width;
/* x = ((u8x8_tile_t *)arg_ptr)->x_pos; x is ignored... no u8x8 support */
u8x8_cad_StartTransfer(u8x8);
/*
Tile structure is reused here for the t6963, however u8x8 is not supported
tile_ptr points to data which has cnt*8 bytes (same as SSD1306 tiles)
Buffer is expected to have 8 lines of code fitting to the t6963 internal memory
"cnt" includes the number of horizontal bytes. width is equal to cnt*8
x is assumed to be zero
TODO: Consider arg_int, however arg_int is not used by u8g2
*/
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
for( i = 0; i < 8; i++ )
{
u8x8_cad_SendCmd(u8x8, 0x0a ); /* display ram (cursor) address low byte */
u8x8_cad_SendArg(u8x8, y&255);
u8x8_cad_SendCmd(u8x8, 0x0b ); /* display ram (cursor) address high byte */
u8x8_cad_SendArg(u8x8, y>>8);
u8x8_cad_SendCmd(u8x8, 0x0c ); /* write start */
/*
The LC7981 has the MSB at the right position, which is exactly the opposite to the T6963.
Instead of writing a third hvline procedure for this device, we just revert the bytes before
transmit. This is slow because:
- the bit reverse itself
- the single byte transfer
The one byte is transmitted via SendArg, which is ok, because CAD = 100
*/
for( j = 0; j < c; j++ )
u8x8_cad_SendArg(u8x8, reverse_byte(*ptr++));
//u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes, send one line of data */
//ptr += u8x8->display_info->tile_width;
y += u8x8->display_info->tile_width;
}
u8x8_cad_EndTransfer(u8x8);
break;
/* handled in the calling procedure
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
break;
*/
/* power save is not there...
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_powersave1_seq);
break;
*/
/* hardware flip not is not available
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
*/
#ifdef U8X8_WITH_SET_CONTRAST
/* no contrast setting :-(
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int );
u8x8_cad_EndTransfer(u8x8);
break;
*/
#endif
default:
return 0;
}
return 1;
}
/*================================================*/
/* LC7981 160x80 LCD*/
static const u8x8_display_info_t u8x8_lc7981_160x80_display_info =
{
/* chip_enable_level = */ 0, /* LC7981 has a low active CS*/
/* chip_disable_level = */ 1,
/* from here... */
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 10,
/* sda_setup_time_ns = */ 30,
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* ... to here, values are ignored, because this is a parallel interface only */
/* data_setup_time_ns = */ 220,
/* write_pulse_width_ns = */ 20,
/* tile_width = */ 20, /* width of 20*8=160 pixel */
/* tile_hight = */ 10,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 160,
/* pixel_height = */ 80
};
static const uint8_t u8x8_d_lc7981_160x80_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(50),
U8X8_CA(0x00, 0x32), /* display on (bit 5), master mode on (bit 4), graphics mode on (bit 1) */
U8X8_CA(0x01, 0x07), /* character/bits per pixel pitch */
U8X8_CA(0x02, 160/8-1), /* number of chars/byte width of the screen */
U8X8_CA(0x03, 0x50), /* time division: 50 (1/80 duty cycle) */
U8X8_CA(0x08, 0x00), /* display start low */
U8X8_CA(0x09, 0x00), /* display start high */
U8X8_DLY(10),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_lc7981_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_lc7981_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_160x80_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_160x80_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/
/* LC7981 160x160 LCD*/
static const u8x8_display_info_t u8x8_lc7981_160x160_display_info =
{
/* chip_enable_level = */ 0, /* LC7981 has a low active CS*/
/* chip_disable_level = */ 1,
/* from here... */
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 10,
/* sda_setup_time_ns = */ 30,
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* ... to here, values are ignored, because this is a parallel interface only */
/* data_setup_time_ns = */ 220,
/* write_pulse_width_ns = */ 20,
/* tile_width = */ 20, /* width of 20*8=160 pixel */
/* tile_hight = */ 20,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 160,
/* pixel_height = */ 160
};
static const uint8_t u8x8_d_lc7981_160x160_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(50),
U8X8_CA(0x00, 0x32), /* display on (bit 5), master mode on (bit 4), graphics mode on (bit 1) */
U8X8_CA(0x01, 0x07), /* character/bits per pixel pitch */
U8X8_CA(0x02, 160/8-1), /* number of chars/byte width of the screen */
U8X8_CA(0x03, 159), /* time division */
U8X8_CA(0x08, 0x00), /* display start low */
U8X8_CA(0x09, 0x00), /* display start high */
U8X8_DLY(10),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_lc7981_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_lc7981_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_160x160_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_160x160_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/
/* LC7981 240x128 LCD*/
static const u8x8_display_info_t u8x8_lc7981_240x128_display_info =
{
/* chip_enable_level = */ 0, /* LC7981 has a low active CS*/
/* chip_disable_level = */ 1,
/* from here... */
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 10,
/* sda_setup_time_ns = */ 30,
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* ... to here, values are ignored, because this is a parallel interface only */
/* data_setup_time_ns = */ 220,
/* write_pulse_width_ns = */ 20,
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 128
};
static const uint8_t u8x8_d_lc7981_240x128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(50),
U8X8_CA(0x00, 0x32), /* display on (bit 5), master mode on (bit 4), graphics mode on (bit 1) */
U8X8_CA(0x01, 0x07), /* character/bits per pixel pitch */
U8X8_CA(0x02, 240/8-1), /* number of chars/byte width of the screen */
U8X8_CA(0x03, 0x7f), /* time division */
U8X8_CA(0x08, 0x00), /* display start low */
U8X8_CA(0x09, 0x00), /* display start high */
U8X8_DLY(10),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_lc7981_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_lc7981_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_240x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_240x128_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/
/* LC7981 240x64 LCD*/
/* https://github.com/olikraus/u8g2/issues/642 */
static const u8x8_display_info_t u8x8_lc7981_240x64_display_info =
{
/* chip_enable_level = */ 0, /* LC7981 has a low active CS*/
/* chip_disable_level = */ 1,
/* from here... */
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 10,
/* sda_setup_time_ns = */ 30,
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* ... to here, values are ignored, because this is a parallel interface only */
/* data_setup_time_ns = */ 220,
/* write_pulse_width_ns = */ 20,
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_lc7981_240x64_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(50),
U8X8_CA(0x00, 0x32), /* display on (bit 5), master mode on (bit 4), graphics mode on (bit 1) */
U8X8_CA(0x01, 0x07), /* character/bits per pixel pitch */
U8X8_CA(0x02, 240/8-1), /* number of chars/byte width of the screen */
U8X8_CA(0x03, 0x7f), /* time division */
U8X8_CA(0x08, 0x00), /* display start low */
U8X8_CA(0x09, 0x00), /* display start high */
U8X8_DLY(10),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_lc7981_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_lc7981_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_lc7981_240x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_240x64_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}

View File

@ -0,0 +1,207 @@
/*
u8x8_d_ld7032_60x32.c
Note: Flip Mode is NOT supported
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* testboard U8GLIB_LD7032_60x32 u8g(11, 12, 9, 10, 8); // SPI Com: SCK = 11, MOSI = 12, CS = 9, A0 = 10, RST = 8 (SW SPI Nano Board) */
/* http://www.seeedstudio.com/document/pdf/0.5OLED%20SPEC.pdf */
static const uint8_t u8x8_d_ld7032_60x32_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
//U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
U8X8_CA(0x014, 0x000), /* Stand-by OFF */
U8X8_CA(0x01a, 0x004), /* Dot Matrix Frame Rate, special value for this OLED from manual*/
U8X8_CA(0x01d, 0x000), /* Graphics Memory Writing Direction: reset default (right down, horizontal) */
U8X8_CA(0x009, 0x000), /* Display Direction: reset default (x,y: min --> max) */
U8X8_CAA(0x030, 0x000, 0x03b), /* Display Size X, Column Start - End*/
U8X8_CAA(0x032, 0x000, 0x01f), /* Display Size Y, Row Start - End*/
U8X8_CA(0x010, 0x000), /* Peak Pulse Width Set: 0 SCLK */
U8X8_CA(0x016, 0x000), /* Peak Pulse Delay Set: 0 SCLK */
U8X8_CA(0x012, 0x040), /* Dot Matrix Current Level Set: 0x050 * 1 uA = 80 uA */
U8X8_CA(0x018, 0x003), /* Pre-Charge Pulse Width: 3 SCLK */
U8X8_CA(0x044, 0x002), /* Pre-Charge Mode: Every Time */
U8X8_CA(0x048, 0x003), /* Row overlap timing: Pre-Charge + Peak Delay + Peak boot Timing */
U8X8_CA(0x03f, 0x011), /* VCC_R_SEL: ??? */
U8X8_CA(0x03d, 0x000), /* VSS selection: 2.8V */
//U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ld7032_60x32_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x002, 0x001), /* Dot Matrix Display ON */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ld7032_60x32_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x002, 0x000), /* Dot Matrix Display ON */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ld7032_60x32_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x009, 0x000), /* Display Direction: reset default (x,y: min --> max) */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ld7032_60x32_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
//U8X8_CA(0x009, 0x002), /* Display Direction: reset default (x,y: min --> max) */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ld7032_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_60x32_display_info);
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_60x32_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x012 );
if ( arg_int > 0x07f ) /* default is 0x040, limit to 0x07f to be on the safe side (hopefully) */
arg_int= 0x07f;
u8x8_cad_SendArg(u8x8, arg_int ); /* values from 0x00 to 0x0ff are allowed, bit will all values be safe??? */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x += u8x8->x_offset/8;
u8x8_cad_SendCmd(u8x8, 0x034 );
u8x8_cad_SendArg(u8x8, x );
u8x8_cad_SendCmd(u8x8, 0x035 );
u8x8_cad_SendArg(u8x8, 0x007 );
u8x8_cad_SendCmd(u8x8, 0x036 );
u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos)*8 );
u8x8_cad_SendCmd(u8x8, 0x037 );
u8x8_cad_SendArg(u8x8, 0x01f );
u8x8_cad_SendCmd(u8x8, 0x008 );
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ld7032_60x32_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 15,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 30, /* 20ns, but cycle time is 60ns, so use 60/2 */
/* sck_pulse_width_ns = */ 30, /* 20ns, but cycle time is 60ns, so use 60/2 */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 20,
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 8,
/* tile_hight = */ 4,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 60,
/* pixel_height = */ 32
};
uint8_t u8x8_d_ld7032_60x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ld7032_60x32_display_info);
return 1;
}
return u8x8_d_ld7032_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,197 @@
/*
u8x8_d_ls013b7dh03.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The LS013B7DH02 is a simple display and controller
--> no support for contrast adjustment, flip and power down.
*/
#include "u8x8.h"
#define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7))
#define LS013B7DH03_CMD_UPDATE (0x01)
#define LS013B7DH03_CMD_ALL_CLEAR (0x04)
#define LS013B7DH03_VAL_TRAILER (0x00)
static const u8x8_display_info_t u8x8_ls013b7dh03_128x128_display_info =
{
/* chip_enable_level = */ 1,
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 50,
/* pre_chip_disable_wait_ns = */ 50,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 227, /* 227 nsec according to the datasheet */
/* sck_pulse_width_ns = */ 255, /* 450 nsec according to the datasheet */
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 2, /* active low, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 100,
/* write_pulse_width_ns = */ 100,
/* tile_width = */ 16,
/* tile_hight = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 128
};
uint8_t u8x8_d_ls013b7dh03_128x128(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
{
uint8_t y, c, i;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ls013b7dh03_128x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
/* clear screen */
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, SWAP8(LS013B7DH03_CMD_ALL_CLEAR) );
u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER);
u8x8_cad_EndTransfer(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
/* not available for the ls013b7dh03 */
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
/* each tile is 8 lines, with the data starting at the left edge */
y = ((((u8x8_tile_t *)arg_ptr)->y_pos) * 8) + 1;
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
/* send data mode byte */
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, SWAP8(LS013B7DH03_CMD_UPDATE) );
/* send 8 lines of 16 bytes (=128 pixels) */
for( i = 0; i < 8; i++ )
{
u8x8_cad_SendCmd(u8x8, SWAP8(y + i) );
u8x8_cad_SendData(u8x8, c, ptr);
u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER);
ptr += c;
}
/* finish with a trailing byte */
u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER);
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ls027b7dh01_400x240_display_info =
{
/* chip_enable_level = */ 1,
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 50,
/* pre_chip_disable_wait_ns = */ 50,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 227, /* 227 nsec according to the datasheet */
/* sck_pulse_width_ns = */ 255, /* 450 nsec according to the datasheet */
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 2, /* active low, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 100,
/* write_pulse_width_ns = */ 100,
/* tile_width = */ 50,
/* tile_hight = */ 30,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 400,
/* pixel_height = */ 240
};
uint8_t u8x8_d_ls027b7dh01_400x240(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ls027b7dh01_400x240_display_info);
break;
default:
return u8x8_d_ls013b7dh03_128x128(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
static const u8x8_display_info_t u8x8_ls013b7dh05_144x168_display_info =
{
/* chip_enable_level = */ 1,
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 50,
/* pre_chip_disable_wait_ns = */ 50,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 227, /* 227 nsec according to the datasheet */
/* sck_pulse_width_ns = */ 255, /* 450 nsec according to the datasheet */
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 2, /* active low, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 100,
/* write_pulse_width_ns = */ 100,
/* tile_width = */ 18,
/* tile_hight = */ 21,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 144,
/* pixel_height = */ 168
};
uint8_t u8x8_d_ls013b7dh05_144x168(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ls013b7dh05_144x168_display_info);
break;
default:
return u8x8_d_ls013b7dh03_128x128(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}

View File

@ -0,0 +1,404 @@
/*
u8x8_d_max7219.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_max7219_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_END_TRANSFER(), /* disable chip */
//U8X8_CA(12, 0), /* shutdown */
//U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_max7219_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_max7219_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_max7219_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t c, j, i;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_powersave1_seq);
break;
*/
/* not supported by MAX7219
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
break;
*/
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
for( i = 0; i < u8x8->display_info->tile_width; i++ )
{
u8x8_cad_SendCmd(u8x8, 10 ); /* brightness */
u8x8_cad_SendArg(u8x8, (arg_int>>4) ); /* 0..15 for contrast */
}
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
/* transfer always has to start at x pos 0 (u8x8 is not supported) */
/* also y pos has to be 0 */
/* arg_int is ignored */
//x = ((u8x8_tile_t *)arg_ptr)->x_pos;
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
for( i = 0; i < 8; i++ )
{
u8x8_cad_StartTransfer(u8x8);
for( j = 0; j < c; j++ )
{
u8x8_cad_SendCmd(u8x8, i+1);
u8x8_cad_SendArg(u8x8, *ptr );
ptr++;
}
u8x8_cad_EndTransfer(u8x8);
}
break;
default:
return 0;
}
return 1;
}
/*==============================*/
static const u8x8_display_info_t u8x8_max7219_32x8_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 100,
/* pre_chip_disable_wait_ns = */ 100,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 100,
/* sck_pulse_width_ns = */ 100,
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150,
/* tile_width = */ 4,
/* tile_hight = */ 1,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 32,
/* pixel_height = */ 8
};
uint8_t u8x8_d_max7219_32x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY :
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_max7219_32x8_display_info);
return 1;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_init_seq);
return 1;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_powersave1_seq);
return 1;
}
return u8x8_d_max7219_generic(u8x8, msg, arg_int, arg_ptr);
}
/*==============================*/
static const u8x8_display_info_t u8x8_max7219_8x8_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 100,
/* pre_chip_disable_wait_ns = */ 100,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 100,
/* sck_pulse_width_ns = */ 100,
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150,
/* tile_width = */ 1,
/* tile_hight = */ 1,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 8,
/* pixel_height = */ 8
};
uint8_t u8x8_d_max7219_8x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY :
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_max7219_8x8_display_info);
return 1;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_init_seq);
return 1;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_powersave1_seq);
return 1;
}
return u8x8_d_max7219_generic(u8x8, msg, arg_int, arg_ptr);
}
/*==============================*/
static const uint8_t u8x8_d_max7219_8_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_CA(15, 0), /* test mode off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_CA(12, 0), /* */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_CA(9, 0), /* decode mode: graphics */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_CA(10, 10), /* medium high intensity */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_CA(11, 7), /* scan limit: display all digits (assuming a 8x8 matrix) */
U8X8_END_TRANSFER(), /* disable chip */
//U8X8_CA(12, 0), /* shutdown */
//U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_max7219_8_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_CA(12, 1), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_max7219_8_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_CA(12, 0), /* shutdown */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_max7219_64x8_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 100,
/* pre_chip_disable_wait_ns = */ 100,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 100,
/* sck_pulse_width_ns = */ 100,
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150,
/* tile_width = */ 8,
/* tile_hight = */ 1,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 64,
/* pixel_height = */ 8
};
uint8_t u8x8_d_max7219_64x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY :
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_max7219_64x8_display_info);
return 1;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_8_init_seq);
return 1;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_8_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_max7219_8_powersave1_seq);
return 1;
}
return u8x8_d_max7219_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,166 @@
/*
u8x8_d_pcd8544_84x48.c (so called "Nokia 5110" displays)
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_pcd8544_84x48_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x021), /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */
U8X8_C(0x006), /* temp. control: b10 = 2 */
U8X8_C(0x013), /* bias system 1:48 */
U8X8_C(0x0c0), /* medium Vop */
U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
U8X8_C(0x008), /* blank */
U8X8_C(0x024), /* power down (PD=1), horizontal increment (V=0), enter normal command set (H=0) */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_pcd8544_84x48_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
U8X8_C(0x00c), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_pcd8544_84x48_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
U8X8_C(0x008), /* blank */
U8X8_C(0x024), /* power down (PD=1), horizontal increment (V=0), enter normal command set (H=0) */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_pcd8544_84x48_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 5,
/* pre_chip_disable_wait_ns = */ 5,
/* reset_pulse_width_ms = */ 2,
/* post_reset_wait_ms = */ 2,
/* sda_setup_time_ns = */ 12,
/* sck_pulse_width_ns = */ 75, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30,
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 11, /* width of 11*8=88 pixel */
/* tile_hight = */ 6,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 84,
/* pixel_height = */ 48
};
uint8_t u8x8_d_pcd8544_84x48(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcd8544_84x48_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_powersave1_seq);
break;
// case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
// break; NOT SUPPORTED
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x021 ); /* command mode, extended function set */
u8x8_cad_SendCmd(u8x8, 0x080 | (arg_int >> 1) );
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x020 ); /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
u8x8_cad_SendCmd(u8x8, 0x080 | (x) ); /* set X address */
u8x8_cad_SendCmd(u8x8, 0x040 | (((u8x8_tile_t *)arg_ptr)->y_pos) ); /* set Y address */
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
do
{
if ( c + x > 84u )
{
if ( x >= 84u )
break;
c = 84u;
c -= x;
}
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
x += c;
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,193 @@
/*
u8x8_d_pcf8812.c
pcf8812: 65x102
pcf8814: 65x96
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_pcf8812_96x65_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
U8X8_C(0x008), /* blank display */
U8X8_C(0x021), /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */
U8X8_C(0x006), /* temp. control: b10 = 2 */
U8X8_C(0x013), /* bias system, 0x010..0x07 1:48 */
U8X8_C(0x09f), /* contrast setting, 0..127 */
//U8X8_CA(0x020 | 2, 0x080 | 0), /* contrast setting, pcf8814 */
U8X8_C(0x024), /* deactivate chip (PD=1), horizontal increment (V=0), enter normal command set (H=0) */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_pcf8812_96x65_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x020), /* power on */
U8X8_C(0x00c), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_pcf8812_96x65_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x020), /* power on */
U8X8_C(0x008), /* blank display */
U8X8_C(0x024), /* power down */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_pcf8812_96x65_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info);
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave1_seq);
break;
/*
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
*/
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x021 ); /* command mode, extended function set */
u8x8_cad_SendArg(u8x8, (arg_int>>1)|0x80 ); /* 0..127 for contrast */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x020 ); /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
u8x8_cad_SendCmd(u8x8, 0x080 | x);
u8x8_cad_SendCmd(u8x8, 0x040 | ((u8x8_tile_t *)arg_ptr)->y_pos);
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
/*
do
{
u8x8_cad_SendData(u8x8, 8, ptr);
ptr += 8;
c--;
} while( c > 0 );
*/
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_pcf8812_96x65_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 100,
/* pre_chip_disable_wait_ns = */ 100,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 100,
/* sck_pulse_width_ns = */ 100,
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150,
/* tile_width = */ 12,
/* tile_hight = */ 9,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 96,
/* pixel_height = */ 65
};
uint8_t u8x8_d_pcf8812_96x65(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info);
return 1;
}
return u8x8_d_pcf8812_96x65_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,198 @@
/*
u8x8_d_pcf8814_hc1230.c
pcf8814: 65x96
hx1230: 68x96
pcf8814 and hc1230 are almost identical.
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_hx1230_96x68_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x020), /* power off */
U8X8_C(0x080), /* contrast setting, 0..31, set to 0 */
U8X8_C(0x0a6), /* not inverted display */
U8X8_C(0x0a4), /* normal display mode */
U8X8_C(0x0a0), /* */
U8X8_C(0x0c0), /* */
U8X8_C(0x040), /* start at scanline 0 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_hx1230_96x68_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x02f), /* power on */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_hx1230_96x68_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* All pixels on = powersave */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_hx1230_96x68_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* */
U8X8_C(0x0c0), /* */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_hx1230_96x68_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* */
U8X8_C(0x0c8), /* */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_hx1230_96x68_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_hx1230_96x68_display_info);
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_hx1230_96x68_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, (arg_int>>3)|0x80 ); /* 0..31 for contrast */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, x&15);
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4));
u8x8_cad_SendCmd(u8x8, 0x0b0 | ((u8x8_tile_t *)arg_ptr)->y_pos);
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_hx1230_96x68_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 100,
/* pre_chip_disable_wait_ns = */ 100,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 100,
/* sck_pulse_width_ns = */ 100,
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150,
/* tile_width = */ 12,
/* tile_hight = */ 9,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 96,
/* pixel_height = */ 68
};
uint8_t u8x8_d_hx1230_96x68(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_hx1230_96x68_display_info);
return 1;
}
return u8x8_d_hx1230_96x68_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,217 @@
/*
u8x8_d_sbn1661.c
SED1520 / SBN1661 122x32 5V LCD
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_sbn1661_init_seq[] = {
U8X8_C(0x0c0), /* display start at line 0 */
U8X8_C(0x0a0), /* a0: ADC forward, a1: ADC reverse */
U8X8_C(0x0a4), /* a4: normal driving, a5: power save */
U8X8_C(0x0a9), /* a8: 1/16, a9: 1/32 duty */
//U8X8_C(0x0af), /* display on */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sbn1661_powersave0_seq[] = {
U8X8_C(0x0af), /* display on */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sbn1661_powersave1_seq[] = {
U8X8_C(0x0ae), /* display off */
U8X8_END() /* end of sequence */
};
struct u8x8_sbn1661_vars
{
uint8_t *ptr;
uint8_t x;
uint8_t c;
uint8_t arg_int;
};
#ifdef NOT_USED
static void u8x8_sbn1661_out(u8x8_t *u8x8, struct u8x8_sbn1661_vars *v, void *arg_ptr)
{
uint8_t cnt;
u8x8_cad_SendCmd(u8x8, 0x000 | ((v->x << 3) & 63) );
u8x8_cad_SendCmd(u8x8, 0x0b8 | (((u8x8_tile_t *)arg_ptr)->y_pos));
while( v->arg_int > 0 )
{
/* calculate tiles to next boundary (end or chip limit) */
cnt = v->x;
cnt += 8;
cnt &= 0x0f8;
cnt -= v->x;
if ( cnt > v->c )
cnt = v->c;
/* of course we still could use cnt=1 here... */
/* but setting cnt to 1 is not very efficient */
//cnt = 1;
v->x +=cnt;
v->c-=cnt;
cnt<<=3;
u8x8_cad_SendData(u8x8, cnt, v->ptr); /* note: SendData can not handle more than 255 bytes */
v->ptr += cnt;
if ( v->c == 0 )
{
v->ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
v->c = ((u8x8_tile_t *)arg_ptr)->cnt;
v->arg_int--;
}
if ( ((v->x) & 7) == 0 )
break;
}
}
#endif /* NOT_USED */
static const u8x8_display_info_t u8x8_sbn1661_122x32_display_info =
{
/* chip_enable_level = */ 0, /* sbn1661: Not used */
/* chip_disable_level = */ 1, /* sbn1661: Not used */
/* post_chip_enable_wait_ns = */ 100,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6, /* */
/* sda_setup_time_ns = */ 12,
/* sck_pulse_width_ns = */ 75, /* sbn1661: Not used */
/* sck_clock_hz = */ 4000000UL, /* sbn1661: Not used */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4, /* sbn1661: Not used */
/* data_setup_time_ns = */ 200,
/* write_pulse_width_ns = */ 200, /* */
/* tile_width = */ 16, /* width of 16*8=128 pixel */
/* tile_hight = */ 4,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 122,
/* pixel_height = */ 32
};
uint8_t u8x8_d_sbn1661_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t *ptr;
//uint8_t x;
//uint8_t c;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sbn1661_122x32_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_init_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_init_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 1, NULL);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_powersave0_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_powersave0_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 1, NULL);
}
else
{
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_powersave1_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
u8x8_cad_SendSequence(u8x8, u8x8_d_sbn1661_powersave1_seq);
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 1, NULL);
}
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
// x and c are ignored (u8g2 only)
//x = ((u8x8_tile_t *)arg_ptr)->x_pos;
//c = ((u8x8_tile_t *)arg_ptr)->cnt;
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
u8x8_cad_SendCmd(u8x8, 0x000 | 0); // column 0
u8x8_cad_SendCmd(u8x8, 0x0b8 | (((u8x8_tile_t *)arg_ptr)->y_pos));
u8x8_cad_SendData(u8x8, 61, ptr); /* note: SendData can not handle more than 255 bytes */
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 0, NULL);
ptr += 61;
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL);
u8x8_cad_SendCmd(u8x8, 0x000 | 0); // column 0
u8x8_cad_SendCmd(u8x8, 0x0b8 | (((u8x8_tile_t *)arg_ptr)->y_pos));
u8x8_cad_SendData(u8x8, 61, ptr); /* note: SendData can not handle more than 255 bytes */
u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 1, NULL);
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_d_sed1520_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
return u8x8_d_sbn1661_122x32(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,351 @@
/*
u8x8_d_sed1330.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The device might also work with the RA8835, SED1335 and SED1336 controller.
The following devices might be compatible:
RA8835
SED1330
SED1335
S1D13700
*/
#include "u8x8.h"
static const uint8_t u8x8_d_sed1330_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x040, 0x030), /* sys init (0x040) with one arg, where 0x030 is a wild guess */
U8X8_CA(0x059, 0x004), /* send display on command (hex 0x059, see p37 ) */
/* display cmd has one arg: 01010100 should enable all three blocks, but disable the cursor*/
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sed1330_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x058, 0x000), /* send display off command (hex 0x059, see p37) and turn of all banks */
/* maybe send a sleep in cmd */
//U8X8_C(0x053) /* sleep in: 0x053 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_sed1330_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t c, i;
uint16_t y;
uint8_t *ptr;
switch(msg)
{
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
/*
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
break;
case U8X8_MSG_DISPLAY_INIT:
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y*=8;
y*= u8x8->display_info->tile_width;
u8x8_cad_StartTransfer(u8x8);
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
for( i = 0; i < 8; i++ )
{
u8x8_cad_SendCmd(u8x8, 0x046 ); /* CSRW command*/
u8x8_cad_SendArg(u8x8, y&255); /* CSRW low adr byte */
u8x8_cad_SendArg(u8x8, y>>8); /* CSRW high adr byte */
u8x8_cad_SendCmd(u8x8, 0x042 ); /* MWRITE */
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes, send one line of data */
ptr += u8x8->display_info->tile_width;
y += u8x8->display_info->tile_width;
}
/* sometimes the display switches off... so just sent a display on command */
u8x8_cad_SendCmd(u8x8, 0x059 ); /* display on */
u8x8_cad_SendArg(u8x8, 0x004); /* arg for display on */
u8x8_cad_EndTransfer(u8x8);
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
break;
default:
return 0;
}
return 1;
}
/*=============================================*/
static const u8x8_display_info_t u8x8_sed1330_240x128_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 30, /* G242CX Datasheet p5 */
/* pre_chip_disable_wait_ns = */ 10, /* G242CX Datasheet p5 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140,
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0,
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 120, /* G242CX Datasheet p5 */
/* write_pulse_width_ns = */ 220, /* G242CX Datasheet p5 */
/* tile_width = */ 0x01e,
/* tile_hight = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 128
};
/* 240x128 Seiko G242C */
static const uint8_t u8x8_d_sed1330_240x128_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(100),
/* system init command, see also u8x8_d_sed1330_powersave0_seq */
U8X8_CA(0x040, 0x030), /* sys init (0x040) with one arg, where 0x030 is a wild guess */
/* system init has total 8 parameters, so 7 more are here */
U8X8_A(0x087), /* no idea here... WF (topmost bit) is set to one because it is suggested in the datasheet, lowest 3 bits refer to text mode only */
U8X8_A(0x007), /* FY: height of a char+1, does not matter here (hopefully), because we use graphics mode only */
U8X8_A(0x01d), /* C/R: this could be the number of horizontal bytes - 1 (Value confirmed with app notes p41) */
U8X8_A(0x050), /* TC/R: According to app notes fOSC=6Mhz fFF=70Hz --> TC/R = 74d*/
U8X8_A(0x080), /* L/F: Lines per frame - 1, probably this is the height of the display - 1 (value confirmed with app notes p41)*/
U8X8_A(0x01e), /* Low byte of the virtual screen size. (Value confirmed with app notes p41) */
U8X8_A(0), /* High byte of the virtual screen size, see also section 9.1.2 */
U8X8_C(0x044), /* SCROLL */
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x080),
U8X8_A(0x000),
U8X8_A(0x040),
U8X8_A(0x080),
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_CA(0x05a, 0), /* HDOT SCR: Horizontal dotwise scroll... set to 0 */
U8X8_CA(0x05b, 0x0c), /* OVLAY: 2-layer, all graphics, OR between layer 1 and 2 */
U8X8_DLY(100),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_DLY(100),
};
/* RA8835 NHD-240128BZ */
static const uint8_t u8x8_d_rh8835_nhd_240128_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(100),
/* system init command, see also u8x8_d_sed1330_powersave0_seq */
U8X8_CA(0x040, 0x030), /* sys init (0x040) with one arg, where 0x030 is a wild guess */
/* system init has total 8 parameters, so 7 more are here */
U8X8_A(0x087), /* no idea here... WF (topmost bit) is set to one because it is suggested in the datasheet, lowest 3 bits refer to text mode only */
U8X8_A(0x007), /* FY: height of a char+1, does not matter here (hopefully), because we use graphics mode only */
U8X8_A(0x01d), /* C/R: this could be the number of horizontal bytes - 1 (Value confirmed with app notes p41) */
U8X8_A(0x050), /* TC/R: According to app notes fOSC=6Mhz fFF=70Hz --> TC/R = 74d*/
U8X8_A(0x080), /* L/F: Lines per frame - 1, probably this is the height of the display - 1 (value confirmed with app notes p41)*/
U8X8_A(0x01e), /* Low byte of the virtual screen size. (Value confirmed with app notes p41) */
U8X8_A(0), /* High byte of the virtual screen size, see also section 9.1.2 */
U8X8_C(0x044), /* SCROLL */
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x080),
U8X8_A(0x000),
U8X8_A(0x040),
U8X8_A(0x080),
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x000),
//U8X8_CA(0x05a, 0), /* HDOT SCR: Horizontal dotwise scroll... set to 0 */
U8X8_CA(0x05b, 0x0c), /* OVLAY: 2-layer, all graphics, OR between layer 1 and 2 */
//U8X8_CA(0x059, 0x04), /* send display on command (hex 0x059, see p37 ) */
U8X8_DLY(100),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_DLY(100),
};
uint8_t u8x8_d_sed1330_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sed1330_240x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_240x128_init_seq);
break;
default:
return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
uint8_t u8x8_d_ra8835_nhd_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sed1330_240x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_rh8835_nhd_240128_init_seq);
break;
default:
return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
/*=============================================*/
static const u8x8_display_info_t u8x8_sed1330_320x240_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 30, /* G242CX Datasheet p5 */
/* pre_chip_disable_wait_ns = */ 10, /* G242CX Datasheet p5 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140,
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0,
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 120, /* G242CX Datasheet p5 */
/* write_pulse_width_ns = */ 220, /* G242CX Datasheet p5 */
/* tile_width = */ 40,
/* tile_hight = */ 30,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 320,
/* pixel_height = */ 240
};
static const uint8_t u8x8_d_sed1330_320x240_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(100),
/* system init command, see also u8x8_d_sed1330_powersave0_seq */
U8X8_CA(0x040, 0x030), /* sys init (0x040) with one arg, where 0x030 is a wild guess */
/* system init has total 8 parameters, so 7 more are here */
U8X8_A(0x087), /* no idea here... WF (topmost bit) is set to one because it is suggested in the datasheet, lowest 3 bits refer to text mode only */
U8X8_A(0x007), /* FY: height of a char+1, does not matter here (hopefully), because we use graphics mode only */
U8X8_A(0x027), /* 40-1 */ /* C/R: this could be the number of horizontal bytes - 1 (Value confirmed with app notes p41) */
U8X8_A(0x039), /* TC/R: According to app notes fOSC=6Mhz fFF=70Hz --> TC/R = 74d*/
U8X8_A(0x0ef), /* L/F: Lines per frame - 1, probably this is the height of the display - 1 (value confirmed with app notes p41)*/
U8X8_A(0x028), /* Low byte of the virtual screen size. (Value confirmed with app notes p41) */
U8X8_A(0), /* High byte of the virtual screen size, see also section 9.1.2 */
U8X8_C(0x044), /* SCROLL */
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x0ef),
U8X8_A(0x0b0),
U8X8_A(0x004),
U8X8_A(0x0ef),
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_CA(0x05a, 0), /* HDOT SCR: Horizontal dotwise scroll... set to 0 */
U8X8_CA(0x05b, 0x0c), /* OVLAY: 2-layer, all graphics, OR between layer 1 and 2 */
U8X8_DLY(100),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_DLY(100),
};
uint8_t u8x8_d_ra8835_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sed1330_320x240_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_320x240_init_seq);
break;
default:
return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}

View File

@ -0,0 +1,215 @@
/*
u8x8_d_sh1106_64x32.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* issue 568 */
static const uint8_t u8x8_d_sh1106_64x32_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x01f), /* multiplex ratio, 0.42 OLED */
U8X8_CA(0x0d3, 0x000), /* display offset, 0.42 OLED */
U8X8_C(0x040), /* set display start line to 0, 0.42 OLED */
U8X8_CA(0xad, 0x8b), /* DC-DC ON/OFF Mode Set: Built-in DC-DC is used, Normal Display (POR = 0x8b) */
U8X8_C(0x33), /* set charge pump voltage 0x30 (POR) .. 0x33 */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1, 0.66 OLED */
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse, 0.66 OLED */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 0.66 OLED */
U8X8_CA(0x081, 0x080), /* [2] set contrast control, 0.42 OLED datasheet: 0xcf */
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1, 0.42 OLED datasheet: 0x22 */
U8X8_CA(0x0db, 0x028), /* vcomh deselect level, 0.42 OLED datasheet: 0x00 */
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1106_64x32_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1106_64x32_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1106_64x32_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0d3, 0), /* display offset, 0.42 OLED */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1106_64x32_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0d3, 0), /* What is the correct offset in flip 1 mode? --> Issue 547 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_sh1106_64x32_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_64x32_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_64x32_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_64x32_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_64x32_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_64x32_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_64x32_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/* copied from SSD1306 */
static const u8x8_display_info_t u8x8_sh1106_64x32_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 8,
/* tile_hight = */ 4,
/* default_x_offset = */ 32,
/* flipmode_x_offset = */ 36,
/* pixel_width = */ 64,
/* pixel_height = */ 32
};
uint8_t u8x8_d_sh1106_64x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_64x32_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_64x32_init_seq);
return 1;
}
return u8x8_d_sh1106_64x32_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,216 @@
/*
u8x8_d_sh1106_72x40.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* WiseChip 0.42 OLED, issue 547 */
static const uint8_t u8x8_d_sh1106_72x40_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x027), /* multiplex ratio, 0.42 OLED */
U8X8_CA(0x0d3, 0x00c), /* display offset, 0.42 OLED */
U8X8_C(0x040), /* set display start line to 0, 0.42 OLED */
U8X8_CA(0xad, 0x8b), /* DC-DC ON/OFF Mode Set: Built-in DC-DC is used, Normal Display (POR = 0x8b) */
U8X8_C(0x33), /* set charge pump voltage 0x30 (POR) .. 0x33 */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1, 0.66 OLED */
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse, 0.66 OLED */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 0.66 OLED */
U8X8_CA(0x081, 0x080), /* [2] set contrast control, 0.42 OLED datasheet: 0xcf */
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1, 0.42 OLED datasheet: 0x22 */
U8X8_CA(0x0db, 0x028), /* vcomh deselect level, 0.42 OLED datasheet: 0x00 */
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1106_72x40_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1106_72x40_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1106_72x40_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0d3, 12), /* display offset, 0.42 OLED */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1106_72x40_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0d3, 52), /* What is the correct offset in flip 1 mode? --> Issue 547 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_sh1106_72x40_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_72x40_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_72x40_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_72x40_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_72x40_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_72x40_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_72x40_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/* copied from SSD1306 */
static const u8x8_display_info_t u8x8_sh1106_72x40_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 9,
/* tile_hight = */ 5,
/* default_x_offset = */ 30,
/* flipmode_x_offset = */ 30,
/* pixel_width = */ 72,
/* pixel_height = */ 40
};
/* WiseChip 0.42" OLED */
uint8_t u8x8_d_sh1106_72x40_wise(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_72x40_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_72x40_init_seq);
return 1;
}
return u8x8_d_sh1106_72x40_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,399 @@
/*
u8x8_d_sh1107.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* code copyied from SSD1306 */
static const uint8_t u8x8_d_sh1107_64x128_noname_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1107_64x128_noname_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1107_64x128_noname_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1107_64x128_noname_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_sh1107_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1107_64x128_noname_display_info);
break;
*/
/* handled by the calling function
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1107_64x128_noname_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1107_64x128_noname_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1107_64x128_noname_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1107_64x128_noname_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1107_64x128_noname_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* sh1107 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
//u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
// set column address
u8x8_cad_SendCmd(u8x8, 0x010 | (x >> 4));
u8x8_cad_SendCmd(u8x8, 0x000 | ((x & 15))); /* probably wrong, should be SendCmd */
// set page address
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos)); /* probably wrong, should be SendCmd */
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
/*
do
{
u8x8_cad_SendData(u8x8, 8, ptr);
ptr += 8;
c--;
} while( c > 0 );
*/
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*==================================================*/
/* QG-6428TSWKG01 */
static const uint8_t u8x8_d_sh1107_64x128_noname_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0dc, 0x000), /* start line */
U8X8_CA(0x081, 0x02f), /* [2] set contrast control */
U8X8_C(0x020), /* use page addressing mode */
// U8X8_C(0x0a1), /* segment remap a0/a1*/
// U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0a8, 0x7f), /* 0x03f) multiplex ratio */
U8X8_CA(0x0d3, 0x060), /* display offset */
U8X8_CA(0x0d5, 0x051), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x035), /* vcomh deselect level */
U8X8_C(0x0b0), /* set page address */
U8X8_CA(0x0da, 0x012), /* set com pins */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_sh1107_64x128_noname_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* sh1107: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* sh1107: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* sh1107: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* sh1107: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 8,
/* tile_height = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 64,
/* pixel_height = */ 128
};
uint8_t u8x8_d_sh1107_64x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_sh1107_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1107_64x128_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1107_64x128_noname_display_info);
break;
default:
return 0;
}
return 1;
}
/*==================================================*/
/* init sequence from Grove OLED 96x96 */
static const uint8_t u8x8_d_sh1107_seeed_96x96_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x050), /* clock divide ratio (0x00=1) and oscillator frequency (0x5) */
U8X8_C(0x020), /* use page addressing mode */
//U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
U8X8_CA(0x0d3, 0x000), /* display offset */
U8X8_CA(0x0dc, 0x000), /* start line */
//U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
//U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x080), /* [2] set contrast control */
U8X8_CA(0x0ad, 0x080), /* */
U8X8_CA(0x0d9, 0x01f), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x027), /* vcomh deselect level */
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
//U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_sh1107_seeed_96x96_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 100, /* cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 100, /* cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* sh1107: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 12,
/* tile_hight = */ 12,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 96,
/* pixel_height = */ 96
};
uint8_t u8x8_d_sh1107_seeed_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_sh1107_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1107_seeed_96x96_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1107_seeed_96x96_display_info);
break;
default:
return 0;
}
return 1;
}
/*==================================================*/
/* 128x128 OLED: this display has a very strange x offset */
/* sequence taken over from 64x128 sequence, because it seems to work mostly */
static const uint8_t u8x8_d_sh1107_128x128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0dc, 0x000), /* start line */
U8X8_CA(0x081, 0x02f), /* [2] set contrast control */
U8X8_C(0x020), /* use page addressing mode */
// U8X8_C(0x0a1), /* segment remap a0/a1*/
// U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0a8, 0x7f), /* 0x03f multiplex ratio */
//U8X8_CA(0x0d3, 0x060), /* display offset (removed, not in datasheet ) */
U8X8_CA(0x0d5, 0x050), /* clock divide ratio (0x00=1) and oscillator frequency (0x8), changed to 0x051, issue 501 */
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x035), /* vcomh deselect level */
U8X8_C(0x0b0), /* set page address */
U8X8_CA(0x0da, 0x012), /* set com pins */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_sh1107_128x128_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 100, /* cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 100, /* cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* sh1107: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 16,
/* default_x_offset = */ 96,
/* flipmode_x_offset = */ 96,
/* pixel_width = */ 128,
/* pixel_height = */ 128
};
uint8_t u8x8_d_sh1107_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_sh1107_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1107_128x128_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1107_128x128_display_info);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,225 @@
/*
u8x8_d_sh1108.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/*
code copyied from sh1107
SH1108: 160x160 controller from Sino Wealth
*/
static const uint8_t u8x8_d_sh1108_noname_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1108_noname_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1108_160x160_noname_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1108_160x160_noname_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_sh1108_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1108_64x128_noname_display_info);
break;
*/
/* handled by the calling function
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1108_64x128_noname_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1108_noname_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1108_noname_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1108_160x160_noname_powersave0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1108_160x160_noname_powersave1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* sh1108 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
//u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
// set column address
u8x8_cad_SendCmd(u8x8, 0x010 | (x >> 4));
u8x8_cad_SendCmd(u8x8, 0x000 | ((x & 15)));
// set page address
u8x8_cad_SendCmd(u8x8, 0x0b0 ); // page cmd is a two byte command
u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*==================================================*/
/* issue #619, 160x160 OLED */
static const uint8_t u8x8_d_sh1108_160x160_noname_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x060), /* clock divide ratio and oscillator frequency */
U8X8_CA(0x0a9, 0x003), /* set display resolution, 0=64x160, 1=96x160, 2=128x160, 3=160x160 */
U8X8_C(0x020), /* use page addressing mode */
U8X8_CA(0x081, 0x01f), /* set contrast control */
U8X8_CA(0x0ad, 0x80), /* DC/DC control 80=Use external Vpp, 89=Use internal DC/DC*/
U8X8_C(0x030), /* set discharge VSL level, 0x030..0x03f */
U8X8_CA(0x0d9, 0x028), /* pre-charge period */
U8X8_CA(0x0db, 0x035), /* vcomh deselect level */
U8X8_CA(0x0dc, 0x035), /* VSEGM Deselect Level */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_sh1108_160x160_noname_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 60,
/* pre_chip_disable_wait_ns = */ 120,
/* reset_pulse_width_ms = */ 100, /* sh1108: 3 us */
/* post_reset_wait_ms = */ 100, /* sometimes OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 100, /* sh1108: 100ns */
/* sck_pulse_width_ns = */ 100, /* sh1108: 100ns */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* sh1108: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 20,
/* tile_height = */ 20,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 160,
/* pixel_height = */ 160
};
uint8_t u8x8_d_sh1108_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_sh1108_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1108_160x160_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1108_160x160_noname_display_info);
break;
default:
return 0;
}
return 1;
}
/*==================================================*/

View File

@ -0,0 +1,287 @@
/*
u8x8_d_sh1122.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copied from sh1122 mostly because of the similar RAM architecture.
However: Commands are very different!
*/
#include "u8x8.h"
static const uint8_t u8x8_d_sh1122_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* sh1122: display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1122_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* sh1122: display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/*
input:
one tile (8 Bytes)
output:
Tile for SH1122 (32 Bytes)
*/
/*
static uint8_t u8x8_sh1122_to32_dest_buf[32];
static uint8_t *u8x8_sh1122_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
{
uint8_t v;
uint8_t a,b;
uint8_t i, j;
uint8_t *dest;
for( j = 0; j < 4; j++ )
{
dest = u8x8_sh1122_to32_dest_buf;
dest += j;
a =*ptr;
ptr++;
b = *ptr;
ptr++;
for( i = 0; i < 8; i++ )
{
v = 0;
if ( a&1 ) v |= 0xf0;
if ( b&1 ) v |= 0x0f;
*dest = v;
dest+=4;
a >>= 1;
b >>= 1;
}
}
return u8x8_sh1122_to32_dest_buf;
}
*/
static uint8_t u8x8_write_byte_to_16gr_device(u8x8_t *u8x8, uint8_t b)
{
static uint8_t buf[4];
static uint8_t map[4] = { 0, 0x00f, 0x0f0, 0x0ff };
buf [3] = map[b & 3];
b>>=2;
buf [2] = map[b & 3];
b>>=2;
buf [1] = map[b & 3];
b>>=2;
buf [0] = map[b & 3];
return u8x8_cad_SendData(u8x8, 4, buf);
}
uint8_t u8x8_d_sh1122_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x;
uint8_t y, c, i;
uint8_t *ptr;
switch(msg)
{
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
/*
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_powersave1_seq);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* sh1122 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 2; // only every 4th col can be addressed
x += u8x8->x_offset;
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y *= 8;
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
for( i = 0; i < 8; i++ )
{
u8x8_cad_SendCmd(u8x8, 0x0b0 ); /* set row address */
u8x8_cad_SendArg(u8x8, y);
u8x8_cad_SendCmd(u8x8, x & 15 ); /* lower 4 bit*/
u8x8_cad_SendCmd(u8x8, 0x010 | (x >> 4) ); /* higher 3 bit */
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
while ( c > 0 )
{
u8x8_write_byte_to_16gr_device(u8x8, *ptr);
c--;
ptr++;
}
y++;
}
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*=========================================================*/
static const uint8_t u8x8_d_sh1122_256x64_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* remap */
U8X8_C(0x0c8), /* remap */
U8X8_C(0x060),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_sh1122_256x64_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* remap */
U8X8_C(0x0c0), /* remap */
U8X8_C(0x040),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_sh1122_256x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 10, /* sh1122: 10 us */
/* post_reset_wait_ms = */ 20, /* */
/* sda_setup_time_ns = */ 125, /* sh1122: cycle time is 250ns, so use 250/2 */
/* sck_pulse_width_ns = */ 125, /* sh1122: cycle time is 250ns, so use 250/2 */
/* sck_clock_hz = */ 40000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 10,
/* write_pulse_width_ns = */ 150, /* sh1122: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 32, /* 256 pixel, so we require 32 bytes for this */
/* tile_hight = */ 8,
/* default_x_offset = */ 0, /* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 256,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_sh1122_256x64_init_seq[] = {
U8X8_DLY(1),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(1),
U8X8_C(0xae), /* display off */
U8X8_C(0x40), /* display start line */
U8X8_C(0x0a0), /* remap */
U8X8_C(0x0c0), /* remap */
U8X8_CA(0x81, 0x80), /* set display contrast */
U8X8_CA(0xa8, 0x3f), /* multiplex ratio 1/64 Duty (0x0F~0x3F) */
U8X8_CA(0xad, 0x81), /* use buildin DC-DC with 0.6 * 500 kHz */
U8X8_CA(0xd5, 0x50), /* set display clock divide ratio (lower 4 bit)/oscillator frequency (upper 4 bit) */
U8X8_CA(0xd3, 0x00), /* display offset, shift mapping ram counter */
U8X8_CA(0xd9, 0x22), /* pre charge (lower 4 bit) and discharge(higher 4 bit) period */
U8X8_CA(0xdb, 0x35), /* VCOM deselect level */
U8X8_CA(0xdc, 0x35), /* Pre Charge output voltage */
U8X8_C(0x030), /* discharge level */
U8X8_DLY(1), /* delay */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_sh1122_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1122_256x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1122_256x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
default:
return u8x8_d_sh1122_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}

View File

@ -0,0 +1,389 @@
/*
u8x8_d_ssd1305.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ssd1305_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1305_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1305_128x32_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0d3, 32), /* display offset to 32 */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1305_128x32_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0d3, 0), /* display offset to */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1305_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendArg(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos) );
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
/*
do
{
u8x8_cad_SendData(u8x8, 8, ptr);
ptr += 8;
c--;
} while( c > 0 );
*/
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_powersave1_seq);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1305 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}
/* timing from SSD1306 */
static const u8x8_display_info_t u8x8_ssd1305_128x32_noname_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 4,
/* default_x_offset = */ 2,
/* flipmode_x_offset = */ 2,
/* pixel_width = */ 128,
/* pixel_height = */ 32
};
static const uint8_t u8x8_d_ssd1305_128x32_noname_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
U8X8_CA(0x0d3, 32), /* display offset to 32 */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1305_128x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1305_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1305_128x32_noname_display_info);
break;
default:
return 0;
}
return 1;
}
/*================================================*/
/* adafruit 128x32 SSD1305 OLED, https://www.adafruit.com/product/2675 */
/* issue 724 */
/* timing from SSD1306 */
static const u8x8_display_info_t u8x8_ssd1305_128x32_adafruit_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 4,
/* default_x_offset = */ 4,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 32
};
uint8_t u8x8_d_ssd1305_128x32_adafruit(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1305_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1305_128x32_adafruit_display_info);
break;
default:
return 0;
}
return 1;
}
/*================================================*/
/* adafruit SSD1305 OLED */
/* timing from SSD1306 */
static const u8x8_display_info_t u8x8_ssd1305_128x64_adafruit_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 2,
/* flipmode_x_offset = */ 2,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_ssd1305_128x64_adafruit_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x0f0), /* clock divide ratio (0x00=1) and oscillator frequency */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
U8X8_CA(0x0d3, 0x040), /* display offset to 32 */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x032), /* [2] set contrast control */
U8X8_CA(0x082, 0x080), /* set area brightness (reset=0x080) */
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1305_128x64_adafruit(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1305_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x32_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1305_128x64_adafruit_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1305_128x64_adafruit_display_info);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,214 @@
/*
u8x8_d_ssd1306_128x32.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* UG-2832HSWEG02 Datasheet, Section 4.4 */
static const uint8_t u8x8_d_ssd1306_128x32_univision_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x01f), /* multiplex ratio */
U8X8_CA(0x0d3, 0x000), /* display offset */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x002), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x08f), /* [2] set contrast control */
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_128x32_univision_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_128x32_univision_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_128x32_univision_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_128x32_univision_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1306_128x32_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x32_univision_display_info);
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x32_univision_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
/*
do
{
u8x8_cad_SendData(u8x8, 8, ptr);
ptr += 8;
c--;
} while( c > 0 );
*/
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1306_128x32_univision_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 4,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 32
};
uint8_t u8x8_d_ssd1306_128x32_univision(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x32_univision_display_info);
return 1;
}
return u8x8_d_ssd1306_128x32_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,465 @@
/*
u8x8_d_ssd1306_128x64_noname.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* more or less generic setup of all these small OLEDs */
static const uint8_t u8x8_d_ssd1306_128x64_noname_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
U8X8_CA(0x0d3, 0x000), /* display offset */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, SSD1306 only, should be removed for SH1106 */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* this setup maximizes the brightness range, that can be set with setContrast() */
/* Drawback: VCOMH deselect level is set to 0, which das not work so good with all OLEDs, issue #116 */
static const uint8_t u8x8_d_ssd1306_128x64_vcomh0_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
U8X8_CA(0x0d3, 0x000), /* display offset */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x0ef), /* [2] set contrast control, */
U8X8_CA(0x0d9, 0x0a1), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x000), /* vcomh deselect level 0x000 .. 0x070, low nibble always 0 */
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* same as u8x8_d_ssd1306_128x64_noname_init_seq, but 0x0da bit 4 is set to 0 */
/* this will disable the alternative COM configuration */
static const uint8_t u8x8_d_ssd1306_128x64_alt0_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
U8X8_CA(0x0d3, 0x000), /* display offset */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, SSD1306 only, should be removed for SH1106 */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x002), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* issue 316: a special sh1106 setup, https://www.mikrocontroller.net/topic/431371?goto=5087807#5087807 */
static const uint8_t u8x8_d_sh1106_128x64_winstar_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0xae), // Display OFF/ON: off (POR = 0xae)
U8X8_C(0xa4), // Set Entire Display OFF/ON: off (POR = 0xa4)
U8X8_CA(0xd5, 0x50), // Divide Ratio/Oscillator FrequencyData Set: divide ratio = 1 (POR = 1), Oscillator Frequency = +/- 0% (POR = +/- 0%)
U8X8_CA(0xa8, 0x3f), // Multiplex Ratio Data Set: 64 (POR = 0x3f, 64)
U8X8_CA(0xd3, 0x00), // Display OffsetData Set: 0 (POR = 0x00)
U8X8_C(0x40), // Set Display Start Line: 0
U8X8_CA(0xad, 0x8b), // DC-DC ON/OFF Mode Set: Built-in DC-DC is used, Normal Display (POR = 0x8b)
U8X8_CA(0xd9, 0x22), // Dis-charge/Pre-charge PeriodData Set: pre-charge 2 DCLKs, dis-charge 2 DCLKs (POR = 0x22, pre-charge 2 DCLKs, dis-charge 2 DCLKs)
U8X8_CA(0xdb, 0x35), // VCOM Deselect LevelData Set: 0,770V (POR = 0x35, 0,770 V)
U8X8_C(0x32), // Set Pump voltage value: 8,0 V (POR = 0x32, 8,0 V)
U8X8_CA(0x81, 0xff), // Contrast Data Register Set: 255 (large) (POR = 0x80)
U8X8_C(0x0a6), // Set Normal/Reverse Display: normal (POR = 0xa6)
U8X8_CA(0x0da, 0x012), // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5)
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_128x64_noname_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_128x64_noname_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_128x64_noname_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_128x64_noname_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1306_sh1106_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
break;
*/
/* handled by the calling function
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendArg(u8x8, 0x000 | ((x&15))); /* probably wrong, should be SendCmd */
u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos)); /* probably wrong, should be SendCmd */
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
/*
do
{
u8x8_cad_SendData(u8x8, 8, ptr);
ptr += 8;
c--;
} while( c > 0 );
*/
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1306_128x64_noname_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_d_ssd1306_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_vcomh0_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_d_ssd1306_128x64_alt0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_alt0_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_sh1106_128x64_noname_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */ 3, /* active low (clock is high by default), rising edge, this seems to be a difference to the ssd1306 */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 2,
/* flipmode_x_offset = */ 2,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
uint8_t u8x8_d_sh1106_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
/* maybe use a better init sequence */
/* https://www.mikrocontroller.net/topic/431371 */
/* the new sequence is added in the winstar constructor (see below), this is kept untouched */
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_d_sh1106_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_vcomh0_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_d_sh1106_128x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_sh1106_128x64_winstar_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1106_128x64_noname_display_info);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,215 @@
/*
u8x8_d_ssd1306_48x64_winstar.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* Winstar 0.71 OLED */
static const uint8_t u8x8_d_ssd1306_48x64_winstar_init_seq[] =
{
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio, 0.71 OLED: changed from 0x2f to 0x3f */
U8X8_CA(0x0d3, 0x000), /* display offset, 0.71 OLED */
U8X8_C(0x040), /* set display start line to 0, 0.71 OLED */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, 0.71 OLED 0x14*/
/// according to the datasheet, 0x00 is NOT page addressing mode, but horizontal addressing mode;
/// so it looks like u8g2 expects horizontal addressing (and the inline comment is wrong) while the Winstar example
/// actually uses page addressing (which is the reset default)
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1, 0.71 OLED */
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse, 0.71 OLED */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 0.71 OLED */
U8X8_CA(0x081, 0x07f), /* [2] set contrast control, 0.71 OLED datasheet: 0x7f */
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1, 0.71 OLED datasheet: 0x22 */
U8X8_CA(0x0db, 0x040), /* vcomh deselect level, 0.71 OLED datasheet: 0x40 */
// U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_48x64_powersave0_seq[] =
{
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_48x64_powersave1_seq[] =
{
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_48x64_flip0_seq[] =
{
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_48x64_flip1_seq[] =
{
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1306_48x64_generic(u8x8_t *u8x8, uint8_t msg,
uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch (msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_48x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_48x64_winstar_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if (arg_int == 0)
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_48x64_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_48x64_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if (arg_int == 0)
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_48x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_48x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081);
u8x8_cad_SendArg(u8x8, arg_int); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *) arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x >> 4));
u8x8_cad_SendCmd(u8x8, 0x000 | ((x & 15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *) arg_ptr)->y_pos));
do
{
c = ((u8x8_tile_t *) arg_ptr)->cnt;
ptr = ((u8x8_tile_t *) arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c * 8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while (arg_int > 0);
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1306_48x64_display_info =
{
/* chip_enable_level = */0,
/* chip_disable_level = */1,
/* post_chip_enable_wait_ns = */20,
/* pre_chip_disable_wait_ns = */10,
/* reset_pulse_width_ms = */100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */4,
/* data_setup_time_ns = */40,
/* write_pulse_width_ns = */150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */6,
/* tile_height = */8,
/* default_x_offset = */40,
/* flipmode_x_offset = */40,
/* pixel_width = */48,
/* pixel_height = */64 };
/* Winstar 0.71" OLED */
uint8_t u8x8_d_ssd1306_48x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
void *arg_ptr)
{
if (msg == U8X8_MSG_DISPLAY_SETUP_MEMORY)
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_48x64_display_info);
return 1;
}
else if (msg == U8X8_MSG_DISPLAY_INIT)
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_48x64_winstar_init_seq);
return 1;
}
return u8x8_d_ssd1306_48x64_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,258 @@
/*
u8x8_d_ssd1306_64x32.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ssd1306_64x32_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_64x32_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_64x32_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_64x32_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1306_64x32_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x32_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_noname_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*======================================================*/
static const u8x8_display_info_t u8x8_ssd1306_64x32_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 8,
/* tile_hight = */ 4,
/* default_x_offset = */ 32,
/* flipmode_x_offset = */ 32,
/* pixel_width = */ 64,
/* pixel_height = */ 32
};
/*======================================================*/
static const uint8_t u8x8_d_ssd1306_64x32_noname_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x02f), /* multiplex ratio: changed from 0x1f to 0x2f */
U8X8_CA(0x0d3, 0x000), /* display offset */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1 */
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control datasheet: 0xcf */
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1 */
U8X8_CA(0x0db, 0x000), /* vcomh deselect level */
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1306_64x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x32_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_noname_init_seq);
return 1;
}
return u8x8_d_ssd1306_64x32_generic(u8x8, msg, arg_int, arg_ptr);
}
/*======================================================*/
static const uint8_t u8x8_d_ssd1306_64x32_1f_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x01f), /* multiplex ratio: changed from 0x1f to 0x2f, 23 Sep 17: changed back to 1f */
U8X8_CA(0x0d3, 0x000), /* display offset */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1 */
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control datasheet: 0xcf */
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1 */
U8X8_CA(0x0db, 0x000), /* vcomh deselect level */
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1306_64x32_1f(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x32_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x32_1f_init_seq);
return 1;
}
return u8x8_d_ssd1306_64x32_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,213 @@
/*
u8x8_d_ssd1306_64x48.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* EastRising 0.66 OLED */
static const uint8_t u8x8_d_ssd1306_64x48_er_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x02f), /* multiplex ratio, 0.66 OLED: changed from 0x1f to 0x2f */
U8X8_CA(0x0d3, 0x000), /* display offset, 0.66 OLED */
U8X8_C(0x040), /* set display start line to 0, 0.66 OLED */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, 0.66 OLED 0x14*/
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1, 0.66 OLED */
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse, 0.66 OLED */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 0.66 OLED */
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control, 0.66 OLED datasheet: 0xcf */
U8X8_CA(0x0d9, 0x022), /* [2] pre-charge period 0x022/f1, 0.66 OLED datasheet: 0x22 */
U8X8_CA(0x0db, 0x000), /* vcomh deselect level, 0.66 OLED datasheet: 0x00 */
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_64x48_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_64x48_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_64x48_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_64x48_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1306_64x48_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x48_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_er_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1306_64x48_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 8,
/* tile_hight = */ 6,
/* default_x_offset = */ 32,
/* flipmode_x_offset = */ 32,
/* pixel_width = */ 64,
/* pixel_height = */ 48
};
/* East Rising 0.66" OLED */
uint8_t u8x8_d_ssd1306_64x48_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_64x48_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_64x48_er_init_seq);
return 1;
}
return u8x8_d_ssd1306_64x48_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,213 @@
/*
u8x8_d_ssd1306_96x16.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* EastRising 0.69 OLED */
static const uint8_t u8x8_d_ssd1306_96x16_er_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x00f), /* multiplex ratio, 0.69 OLED: 0x0f */
U8X8_CA(0x0d3, 0x000), /* display offset, 0.69 OLED */
U8X8_C(0x040), /* set display start line to 0, 0.69 OLED */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, 0.66 OLED 0x14*/
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1, 0.66 OLED */
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse, 0.66 OLED */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x002), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), 0.66 OLED */
U8X8_CA(0x081, 0x0af), /* [2] set contrast control, 0.69 OLED datasheet: 0xaf */
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x0f1, 0.69 OLED datasheet: 0xf1 */
U8X8_CA(0x0db, 0x020), /* vcomh deselect level, 0.69 OLED datasheet: 0x20 */
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_96x16_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_96x16_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_96x16_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1306_96x16_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1306_96x16_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_96x16_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_er_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1306_96x16_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 12,
/* tile_hight = */ 2,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 32,
/* pixel_width = */ 96,
/* pixel_height = */ 16
};
/* East Rising 0.69" OLED */
uint8_t u8x8_d_ssd1306_96x16_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_96x16_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x16_er_init_seq);
return 1;
}
return u8x8_d_ssd1306_96x16_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,288 @@
/*
u8x8_d_ssd1309.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ssd1309_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1309_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1309_128x64_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1309_128x64_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1309_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos) );
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
/*
do
{
u8x8_cad_SendData(u8x8, 8, ptr);
ptr += 8;
c--;
} while( c > 0 );
*/
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_powersave1_seq);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1309 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}
/*=================================================*/
/* offset 2 version */
/* timing from SSD1306 */
static const u8x8_display_info_t u8x8_ssd1309_128x64_noname2_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 2,
/* flipmode_x_offset = */ 2,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_ssd1309_128x64_noname_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x0a0), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
//U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x020, 0x002), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x06f), /* [2] set contrast control */
U8X8_CA(0x0d9, 0x0d3), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x020), /* vcomh deselect level */
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
//U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1309_128x64_noname2(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1309_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1309_128x64_noname2_display_info);
break;
default:
return 0;
}
return 1;
}
/*=================================================*/
/* offset 0 version */
/* timing from SSD1306 */
static const u8x8_display_info_t u8x8_ssd1309_128x64_noname0_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
uint8_t u8x8_d_ssd1309_128x64_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1309_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1309_128x64_noname0_display_info);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,237 @@
/*
u8x8_d_ssd1317.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SSD1317: 128x96 OLED
*/
#include "u8x8.h"
/* more or less generic setup of all these small OLEDs */
static const uint8_t u8x8_d_ssd1317_96x96_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0d5, 0x080), /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio */
U8X8_CA(0x0d3, 0x000), /* display offset */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_CA(0x08d, 0x014), /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, SSD1306 only, should be removed for SH1106 */
U8X8_CA(0x020, 0x000), /* page addressing mode */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
// Flipmode
// U8X8_C(0x0a0), /* segment remap a0/a1*/
// U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_CA(0x0da, 0x012), /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
U8X8_CA(0x081, 0x0cf), /* [2] set contrast control */
U8X8_CA(0x0d9, 0x0f1), /* [2] pre-charge period 0x022/f1*/
U8X8_CA(0x0db, 0x040), /* vcomh deselect level */
// if vcomh is 0, then this will give the biggest range for contrast control issue #98
// restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
U8X8_C(0x02e), /* Deactivate scroll */
U8X8_C(0x0a4), /* output ram to display */
U8X8_C(0x0a6), /* none inverted normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1317_96x96_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1317_96x96_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1317_96x96_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1317_96x96_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_ssd1317_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1317_96x96_display_info);
break;
*/
/* handled by the calling function
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1317_96x96_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1317_96x96_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1317_96x96_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1317_96x96_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1317_96x96_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1306 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendArg(u8x8, 0x000 | ((x&15))); /* probably wrong, should be SendCmd */
u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos)); /* probably wrong, should be SendCmd */
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
/*
do
{
u8x8_cad_SendData(u8x8, 8, ptr);
ptr += 8;
c--;
} while( c > 0 );
*/
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1317_96x96_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1306: 3 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150, /* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 12,
/* tile_hight = */ 12,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 96,
/* pixel_height = */ 96
};
uint8_t u8x8_d_ssd1317_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1317_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1317_96x96_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1317_96x96_display_info);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,533 @@
/*
u8x8_d_ssd1322.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SSD1322:
480 x 128 dot matrix
16 gray scale
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ssd1322_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* ssd1322: display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1322_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* ssd1322: display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* interpret b as a monochrome bit pattern, write value 15 for high bit and value 0 for a low bit */
/* topbit (msb) is sent last */
/* example: b = 0x083 will send 0xff, 0x00, 0x00, 0xf0 */
/* 4 Jan 2017: I think this procedure not required any more. Delete? */
/*
static uint8_t u8x8_write_byte_to_16gr_device(u8x8_t *u8x8, uint8_t b)
{
static uint8_t buf[4];
static uint8_t map[4] = { 0, 0x00f, 0x0f0, 0x0ff };
buf [3] = map[b & 3];
b>>=2;
buf [2] = map[b & 3];
b>>=2;
buf [1] = map[b & 3];
b>>=2;
buf [0] = map[b & 3];
return u8x8_cad_SendData(u8x8, 4, buf);
}
*/
/*
input:
one tile (8 Bytes)
output:
Tile for SSD1325 (32 Bytes)
*/
static uint8_t u8x8_ssd1322_to32_dest_buf[32];
static uint8_t *u8x8_ssd1322_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
{
uint8_t v;
uint8_t a,b;
uint8_t i, j;
uint8_t *dest;
for( j = 0; j < 4; j++ )
{
dest = u8x8_ssd1322_to32_dest_buf;
dest += j;
a =*ptr;
ptr++;
b = *ptr;
ptr++;
for( i = 0; i < 8; i++ )
{
v = 0;
if ( a&1 ) v |= 0xf0;
if ( b&1 ) v |= 0x0f;
*dest = v;
dest+=4;
a >>= 1;
b >>= 1;
}
}
return u8x8_ssd1322_to32_dest_buf;
}
static uint8_t *u8x8_ssd1322_4to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
{
uint8_t v;
uint8_t a;
uint8_t i, j;
uint8_t *dest;
for( j = 0; j < 4; j++ )
{
dest = u8x8_ssd1322_to32_dest_buf;
dest += j;
a =*ptr;
ptr++;
for( i = 0; i < 8; i++ )
{
v = 0;
if ( a&1 ) v = 0xff;
*dest = v;
dest+=4;
a >>= 1;
}
}
return u8x8_ssd1322_to32_dest_buf;
}
uint8_t u8x8_d_ssd1322_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x;
uint8_t y, c;
uint8_t *ptr;
switch(msg)
{
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
/*
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_powersave1_seq);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x0C1 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1322 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 2; // only every 4th col can be addressed
x += u8x8->x_offset;
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y *= 8;
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address, moved out of the loop (issue 302) */
u8x8_cad_SendArg(u8x8, y);
u8x8_cad_SendArg(u8x8, y+7);
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
u8x8_cad_SendArg(u8x8, x ); /* start */
u8x8_cad_SendArg(u8x8, x+1 ); /* end */
u8x8_cad_SendCmd(u8x8, 0x05c ); /* write to ram */
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1322_8to32(u8x8, ptr));
ptr += 8;
x += 2;
c--;
} while( c > 0 );
//x += 2;
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*=========================================================*/
static const uint8_t u8x8_d_ssd1322_256x64_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CAA(0x0a0, 0x006, 0x011), /* remap */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1322_256x64_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CAA(0x0a0, 0x014, 0x011), /* remap */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_ssd1322_256x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1322: 2 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1322: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1322: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 10000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215), 10 MHz (issue 301) */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 10,
/* write_pulse_width_ns = */ 150, /* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 32, /* 256 pixel, so we require 32 bytes for this */
/* tile_hight = */ 8,
/* default_x_offset = */ 0x01c, /* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
/* flipmode_x_offset = */ 0x01c,
/* pixel_width = */ 256,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_ssd1322_256x64_init_seq[] = {
U8X8_DLY(1),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(1),
U8X8_CA(0xfd, 0x12), /* unlock */
U8X8_C(0xae), /* display off */
U8X8_CA(0xb3, 0x91), /* set display clock divide ratio/oscillator frequency (set clock as 80 frames/sec) */
U8X8_CA(0xca, 0x3f), /* multiplex ratio 1/64 Duty (0x0F~0x3F) */
U8X8_CA(0xa2, 0x00), /* display offset, shift mapping ram counter */
U8X8_CA(0xa1, 0x00), /* display start line */
//U8X8_CAA(0xa0, 0x14, 0x11), /* Set Re-Map / Dual COM Line Mode */
U8X8_CAA(0xa0, 0x06, 0x011), /* Set Re-Map / Dual COM Line Mode */
U8X8_CA(0xab, 0x01), /* Enable Internal VDD Regulator */
U8X8_CAA(0xb4, 0xa0, 0x005|0x0fd), /* Display Enhancement A */
U8X8_CA(0xc1, 0x9f), /* contrast */
U8X8_CA(0xc7, 0x0f), /* Set Scale Factor of Segment Output Current Control */
U8X8_C(0xb9), /* linear grayscale */
U8X8_CA(0xb1, 0xe2), /* Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment */
U8X8_CAA(0xd1, 0x082|0x020, 0x020), /* Display Enhancement B */
U8X8_CA(0xbb, 0x1f), /* precharge voltage */
U8X8_CA(0xb6, 0x08), /* precharge period */
U8X8_CA(0xbe, 0x07), /* vcomh */
U8X8_C(0xa6), /* normal display */
U8X8_C(0xa9), /* exit partial display */
U8X8_DLY(1), /* delay 2ms */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1322_nhd_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1322_256x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
default:
return u8x8_d_ssd1322_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
/*=========================================================*/
/*
NHD-2.7-12864WDW3-M
http://www.newhavendisplay.com/nhd2712864wdw3m-p-9546.html
http://www.newhavendisplay.com/specs/NHD-2.7-12864WDW3-M.pdf
It looks like that only every second pixel is connected to the OLED
*/
uint8_t u8x8_d_ssd1322_common2(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x;
uint8_t y, c;
uint8_t *ptr;
switch(msg)
{
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
/*
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_powersave1_seq);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x0C1 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1322 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 2; // only every 4th col can be addressed
x *= 2; // only every second pixel is used in the 128x64 NHD OLED
x += u8x8->x_offset;
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y *= 8;
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address, moved out of the loop (issue 302) */
u8x8_cad_SendArg(u8x8, y);
u8x8_cad_SendArg(u8x8, y+7);
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
u8x8_cad_SendArg(u8x8, x ); /* start */
u8x8_cad_SendArg(u8x8, x+1 ); /* end */
u8x8_cad_SendCmd(u8x8, 0x05c ); /* write to ram */
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1322_4to32(u8x8, ptr));
ptr += 4;
x += 2;
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
u8x8_cad_SendArg(u8x8, x ); /* start */
u8x8_cad_SendArg(u8x8, x+1 ); /* end */
u8x8_cad_SendCmd(u8x8, 0x05c ); /* write to ram */
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1322_4to32(u8x8, ptr));
ptr += 4;
x += 2;
c--;
} while( c > 0 );
//x += 2;
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const uint8_t u8x8_d_ssd1322_128x64_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CAA(0x0a0, 0x016, 0x011), /* remap */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1322_128x64_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CAA(0x0a0, 0x004, 0x011), /* remap */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_ssd1322_128x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100, /* SSD1322: 2 us */
/* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
/* sda_setup_time_ns = */ 50, /* SSD1322: 15ns, but cycle time is 100ns, so use 100/2 */
/* sck_pulse_width_ns = */ 50, /* SSD1322: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 10000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215), 10 MHz (issue 301) */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 10,
/* write_pulse_width_ns = */ 150, /* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
/* tile_width = */ 16, /* 128 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 28, /* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
/* flipmode_x_offset = */ 28,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_ssd1322_128x64_init_seq[] = {
U8X8_DLY(1),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(1),
U8X8_CA(0xfd, 0x12), /* unlock */
U8X8_C(0xae), /* display off */
U8X8_CA(0xb3, 0x91), /* set display clock divide ratio/oscillator frequency (set clock as 80 frames/sec) */
U8X8_CA(0xca, 0x3f), /* multiplex ratio 1/64 Duty (0x0F~0x3F) */
U8X8_CA(0xa2, 0x00), /* display offset, shift mapping ram counter */
U8X8_CA(0xa1, 0x00), /* display start line */
U8X8_CA(0xab, 0x01), /* Enable Internal VDD Regulator */
//U8X8_CAA(0xa0, 0x14, 0x11), /* Set Re-Map / Dual COM Line Mode */
//U8X8_CAA(0xa0, 0x06, 0x011), /* Set Re-Map / Dual COM Line Mode */
U8X8_CAA(0xa0, 0x16, 0x011), /* Set Re-Map / Dual COM Line Mode (NHD-2.7-12864WDW3-M datasheet) */
U8X8_CA(0xc7, 0x0f), /* Set Scale Factor of Segment Output Current Control */
U8X8_CA(0xc1, 0x9f), /* contrast */
//U8X8_CA(0xb1, 0xe2), /* Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment */
U8X8_CA(0xb1, 0xf2), /* Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment (NHD-2.7-12864WDW3-M datasheet) */
U8X8_CA(0xbb, 0x1f), /* precharge voltage */
//U8X8_CAA(0xb4, 0xa0, 0x005|0x0fd), /* Display Enhancement A */
U8X8_CAA(0xb4, 0xa0, 0x0fd), /* Display Enhancement A (NHD-2.7-12864WDW3-M datasheet) */
U8X8_CA(0xbe, 0x04), /* vcomh (NHD-2.7-12864WDW3-M datasheet) */
U8X8_C(0xb9), /* linear grayscale */
//U8X8_CAA(0xd1, 0x082|0x020, 0x020), /* Display Enhancement B */
//U8X8_CA(0xb6, 0x08), /* precharge period */
U8X8_C(0xa6), /* normal display */
U8X8_C(0xa9), /* exit partial display */
U8X8_DLY(1), /* delay 2ms */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1322_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1322_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_128x64_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_128x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_128x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
default:
return u8x8_d_ssd1322_common2(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}

View File

@ -0,0 +1,435 @@
/*
u8x8_d_ssd1325.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SSD1325:
128 x 80, 16 Gray Scale Dot Matrix
SSD0323: Identical to SSD1325, issue 720
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ssd1325_128x64_nhd_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1325_128x64_nhd_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1325_128x64_nhd_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a0, 0x052), /* remap */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1325_128x64_nhd_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a0, 0x041), /* remap */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/*
input:
one tile (8 Bytes)
output:
Tile for SSD1325 (32 Bytes)
*/
static uint8_t u8x8_ssd1325_8to32_dest_buf[32];
static uint8_t *u8x8_ssd1325_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
{
uint8_t v;
uint8_t a,b;
uint8_t i, j;
uint8_t *dest;
for( j = 0; j < 4; j++ )
{
dest = u8x8_ssd1325_8to32_dest_buf;
dest += j;
a =*ptr;
ptr++;
b = *ptr;
ptr++;
for( i = 0; i < 8; i++ )
{
v = 0;
if ( a&1 ) v |= 0xf0;
if ( b&1 ) v |= 0x0f;
*dest = v;
dest+=4;
a >>= 1;
b >>= 1;
}
}
return u8x8_ssd1325_8to32_dest_buf;
}
/*===================================================================*/
static uint8_t u8x8_d_ssd1325_128x64_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1325_128x64_nhd_display_info);
break;
*/
/* handled by the calling function
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_powersave1_seq);
break;
/* handled by the calling function
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
*/
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1325 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 4;
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y *= 8;
y += u8x8->x_offset; /* x_offset is used as y offset for the SSD1325 */
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address */
u8x8_cad_SendArg(u8x8, y);
u8x8_cad_SendArg(u8x8, y+7);
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
if ( ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] | ptr[7] )
{
/* draw the tile if pattern is not zero for all bytes */
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
u8x8_cad_SendArg(u8x8, x ); /* start */
u8x8_cad_SendArg(u8x8, x+3 ); /* end */
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1325_8to32(u8x8, ptr));
}
else
{
/* tile is empty, use the graphics acceleration command */
u8x8_cad_SendCmd(u8x8, 0x024 ); // draw rectangle
u8x8_cad_SendArg(u8x8, x );
u8x8_cad_SendArg(u8x8, y );
u8x8_cad_SendArg(u8x8, x+3 );
u8x8_cad_SendArg(u8x8, y+7 );
u8x8_cad_SendArg(u8x8, 0 ); // clear
}
ptr += 8;
x += 4;
c--;
} while( c > 0 );
//x += 4;
arg_int--;
} while( arg_int > 0 );
u8x8_cad_SendCmd(u8x8, 0xe3); // no-op needs to be sent after last byte before cs is toggled.
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*===================================================================*/
/* http://www.newhavendisplay.com/app_notes/OLED_2_7_12864.txt */
static const uint8_t u8x8_d_ssd1325_128x64_nhd_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a1, 0x000), /* display start line */
U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
U8X8_CA(0x0a0, 0x052), /* remap configuration, horizontal address increment (bit 2 = 0), enable nibble remap (upper nibble is left, bit 1 = 1) */
U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
U8X8_C(0x0b8), /* set gray scale table */
U8X8_A(0x001), /* */
U8X8_A(0x011), /* */
U8X8_A(0x022), /* */
U8X8_A(0x032), /* */
U8X8_A(0x043), /* */
U8X8_A(0x054), /* */
U8X8_A(0x065), /* */
U8X8_A(0x076), /* */
U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128, Newhaven: 0x040 */
U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
U8X8_CA(0x0b1, 0x055), /* phase length */
U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_C(0x0a4), /* normal display mode */
U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_nhd_ssd1325_128x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100, /**/
/* sda_setup_time_ns = */ 100, /* SSD1325 */
/* sck_pulse_width_ns = */ 100, /* SSD1325 */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 60, /* SSD1325 */
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0, /* x_offset is used as y offset for the SSD1325 */
/* flipmode_x_offset = */ 8, /* x_offset is used as y offset for the SSD1325 */
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
uint8_t u8x8_d_ssd1325_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_nhd_ssd1325_128x64_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_init_seq);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
{
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1325_128x64_nhd_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
return 1;
}
return u8x8_d_ssd1325_128x64_generic(u8x8, msg, arg_int, arg_ptr);
}
/*===================================================================*/
/* OSRAM Pictiva 128x64 OLED */
/* https://github.com/olikraus/u8g2/issues/720 */
static const uint8_t u8x8_d_ssd0323_os128064_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
U8X8_CA(0x0a2, 0x040), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a1, 0x000), /* display start line */
U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
U8X8_CA(0x0a0, 0x052), /* remap configuration, horizontal address increment (bit 2 = 0), enable nibble remap (upper nibble is left, bit 1 = 1) */
U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
U8X8_C(0x0b8), /* set gray scale table */
U8X8_A(0x001), /* */
U8X8_A(0x011), /* */
U8X8_A(0x022), /* */
U8X8_A(0x032), /* */
U8X8_A(0x043), /* */
U8X8_A(0x054), /* */
U8X8_A(0x065), /* */
U8X8_A(0x076), /* */
U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128, Newhaven: 0x040 */
U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
U8X8_CA(0x0b1, 0x055), /* phase length */
U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_C(0x0a4), /* normal display mode */
U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd0323_os128064_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a0, 0x052), /* remap */
U8X8_CA(0x0a2, 0x040), /* display offset, shift mapping ram counter */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd0323_os128064_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a0, 0x041), /* remap */
U8X8_CA(0x0a2, 0x050), /* display offset, shift mapping ram counter */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_ssd0323_os128064_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100, /**/
/* sda_setup_time_ns = */ 100, /* SSD1325 */
/* sck_pulse_width_ns = */ 100, /* SSD1325 */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 60, /* SSD1325 */
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0, /* x_offset is used as y offset for the SSD1325 */
/* flipmode_x_offset = */ 0, /* x_offset is used as y offset for the SSD1325 */
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
uint8_t u8x8_d_ssd0323_os128064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd0323_os128064_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd0323_os128064_init_seq);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
{
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd0323_os128064_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd0323_os128064_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
return 1;
}
return u8x8_d_ssd1325_128x64_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,277 @@
/*
u8x8_d_ssd1326.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* ER OLED */
static const uint8_t u8x8_d_ssd1326_er_256x32_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0fd, 0x012), /* unlock (not required, this is default by reset) */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0a8, 0x01f), /* multiplex ratio: 0x03f * 1/64 duty - changed by CREESOO, acc. to datasheet, 100317*/
U8X8_CA(0x0a1, 0x000), /* display start line */
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
/*
a0 command: 0x0a0 ***abcde
a: 1: mono mode
b: 0: horizontal (1: vertical) address increment
c: 1: enable bit remap
d: 1: COM remap
e: 1: Column remap
*/
U8X8_CA(0x0a0, 0x006), /* remap configuration, see above */
U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
U8X8_C(0x0b7), /* set default gray scale table */
U8X8_CA(0x081, 0x027), /* contrast, brightness, 0..128 */
U8X8_CA(0x0b1, 0x071), /* phase length */
//U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
U8X8_CA(0x0b3, 0x0f0), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
//U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
//U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_CAA(0x0bb, 0x035, 0x0ff), /* set precharge */
U8X8_CA(0x0bc, 0x01f), /* pre-charge voltage level */
U8X8_CA(0x0be, 0x00f), /* VCOMH voltage */
U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_C(0x0a4), /* normal display mode */
//U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1326_256x32_nhd_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1326_256x32_nhd_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1326_256x32_nhd_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a0, 0x006), /* remap 00110 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1326_256x32_nhd_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
//U8X8_CA(0x0a0, 0x005), /* remap 00101 */
U8X8_CA(0x0a0, 0x001), /* remap 00001 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/*
input:
one tile (8 Bytes)
output:
Tile for ssd1326 (32 Bytes)
*/
static uint8_t u8x8_ssd1326_8to32_dest_buf[32];
static uint8_t *u8x8_ssd1326_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
{
uint8_t v;
uint8_t a,b;
uint8_t i, j;
uint8_t *dest;
for( j = 0; j < 4; j++ )
{
dest = u8x8_ssd1326_8to32_dest_buf;
dest += j;
a =*ptr;
ptr++;
b = *ptr;
ptr++;
for( i = 0; i < 8; i++ )
{
v = 0;
if ( a&1 ) v |= 0xf0;
if ( b&1 ) v |= 0x0f;
*dest = v;
dest+=4;
a >>= 1;
b >>= 1;
}
}
return u8x8_ssd1326_8to32_dest_buf;
}
static uint8_t u8x8_d_ssd1326_256x32_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1326_256x32_nhd_display_info);
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_er_256x32_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_256x32_nhd_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_256x32_nhd_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_256x32_nhd_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1326_256x32_nhd_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1326 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 4;
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y *= 8;
y += u8x8->x_offset; /* x_offset is used as y offset for the ssd1326 */
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
u8x8_cad_SendArg(u8x8, x ); /* start */
u8x8_cad_SendArg(u8x8, x+3 ); /* end */
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address */
u8x8_cad_SendArg(u8x8, y);
u8x8_cad_SendArg(u8x8, y+7);
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1326_8to32(u8x8, ptr));
ptr += 8;
x += 4;
c--;
} while( c > 0 );
//x += 4;
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1326_256x32_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 15,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100, /**/
/* sda_setup_time_ns = */ 100, /* ssd1326 */
/* sck_pulse_width_ns = */ 100, /* ssd1326 */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 60, /* ssd1326 */
/* tile_width = */ 32,
/* tile_hight = */ 4,
/* default_x_offset = */ 0, /* x_offset is used as y offset for the ssd1326 */
/* flipmode_x_offset = */ 0, /* x_offset is used as y offset for the ssd1326 */
/* pixel_width = */ 256,
/* pixel_height = */ 32
};
uint8_t u8x8_d_ssd1326_er_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1326_256x32_display_info);
return 1;
}
return u8x8_d_ssd1326_256x32_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,571 @@
/*
u8x8_d_ssd1327.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ssd1327_96x96_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1327_96x96_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/*
input:
one tile (8 Bytes)
output:
Tile for ssd1327 (32 Bytes)
*/
static uint8_t u8x8_ssd1327_8to32_dest_buf[32];
static uint8_t *u8x8_ssd1327_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
{
uint8_t v;
uint8_t a,b;
uint8_t i, j;
uint8_t *dest;
for( j = 0; j < 4; j++ )
{
dest = u8x8_ssd1327_8to32_dest_buf;
dest += j;
a =*ptr;
ptr++;
b = *ptr;
ptr++;
for( i = 0; i < 8; i++ )
{
v = 0;
if ( a&1 ) v |= 0xf0;
if ( b&1 ) v |= 0x0f;
*dest = v;
dest+=4;
a >>= 1;
b >>= 1;
}
}
return u8x8_ssd1327_8to32_dest_buf;
}
static uint8_t u8x8_d_ssd1327_96x96_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_96x96_display_info);
break;
*/
/* handled by the calling function
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_powersave1_seq);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1327 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 4;
x+=u8x8->x_offset/2;
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y *= 8;
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address, moved out of the loop (issue 302) */
u8x8_cad_SendArg(u8x8, y);
u8x8_cad_SendArg(u8x8, y+7);
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
u8x8_cad_SendArg(u8x8, x ); /* start */
u8x8_cad_SendArg(u8x8, x+3 ); /* end */
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1327_8to32(u8x8, ptr));
ptr += 8;
x += 4;
c--;
} while( c > 0 );
//x += 4;
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*=============================================*/
/* Seeedstudio Grove OLED 96x96 */
static const u8x8_display_info_t u8x8_ssd1327_96x96_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100, /**/
/* sda_setup_time_ns = */ 100, /* */
/* sck_pulse_width_ns = */ 100, /* */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 1, /* use 1 instead of 4, because the SSD1327 seems to be very slow */
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 60,
/* tile_width = */ 12,
/* tile_hight = */ 12,
/* default_x_offset = */ 16,
/* flipmode_x_offset = */ 16,
/* pixel_width = */ 96,
/* pixel_height = */ 96
};
/* https://github.com/SeeedDocument/Grove_OLED_1.12/raw/master/resources/LY120-096096.pdf */
/* http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96 */
/* values from u8glib */
/*
Re-map setting in Graphic Display Data RAM, command 0x0a0
Bit 0: Column Address Re-map
Bit 1: Nibble Re-map
Bit 2: Horizontal/Vertical Address Increment
Bit 3: Not used, must be 0
Bit 4: COM Re-map
Bit 5: Not used, must be 0
Bit 6: COM Split Odd Even
Bit 7: Not used, must be 0
*/
static const uint8_t u8x8_d_ssd1327_96x96_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0fd, 0x012), /* unlock display, usually not required because the display is unlocked after reset */
U8X8_C(0x0ae), /* display off */
//U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x05f * 1/64 duty */
U8X8_CA(0x0a1, 0x000), /* display start line */
//U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a2, 0x020), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x051), /* remap configuration */
U8X8_CA(0x0ab, 0x001), /* Enable internal VDD regulator (RESET) */
//U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */
U8X8_CA(0x081, 0x053), /* contrast, brightness, 0..128 */
//U8X8_CA(0x0b1, 0x055), /* phase length */
U8X8_CA(0x0b1, 0x051), /* phase length */
//U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
U8X8_CA(0x0b3, 0x001), /* set display clock divide ratio/oscillator frequency */
//? U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
//? U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
U8X8_C(0x0b9), /* use linear lookup table */
//U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
U8X8_CA(0x0bc, 0x008), /* pre-charge voltage level */
//U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
U8X8_CA(0x0be, 0x007), /* VCOMH voltage */
U8X8_CA(0x0b6, 0x001), /* second precharge */
U8X8_CA(0x0d5, 0x062), /* enable second precharge, internal vsl (bit0 = 0) */
U8X8_C(0x0a4), /* normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1327_seeed_96x96_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a2, 0x020), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x051), /* remap configuration */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1327_seeed_96x96_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a2, 0x060), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x042), /* remap configuration */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1327_seeed_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_96x96_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_96x96_init_seq);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
{
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_seeed_96x96_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_seeed_96x96_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
return 1;
}
return 0;
}
/*=============================================*/
/* EA W128128 round OLED 128x128 */
/* issue #641 */
/* https://www.lcd-module.de/fileadmin/eng/pdf/grafik/W128128-XR.pdf */
static const u8x8_display_info_t u8x8_ssd1327_ea_w128128_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100, /**/
/* sda_setup_time_ns = */ 100, /* */
/* sck_pulse_width_ns = */ 100, /* */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 1, /* use 1 instead of 4, because the SSD1327 seems to be very slow */
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 60,
/* tile_width = */ 16,
/* tile_hight = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 128
};
/* this is a copy of the init sequence for the seeed 96x96 oled */
static const uint8_t u8x8_d_ssd1327_ea_w128128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0fd, 0x012), /* unlock display, usually not required because the display is unlocked after reset */
U8X8_C(0x0ae), /* display off */
//U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x05f * 1/64 duty */
U8X8_CA(0x0a1, 0x000), /* display start line */
//U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a2, 0x010), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x051), /* remap configuration */
U8X8_CA(0x0ab, 0x001), /* Enable internal VDD regulator (RESET) */
//U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */
U8X8_CA(0x081, 0x053), /* contrast, brightness, 0..128 */
//U8X8_CA(0x0b1, 0x055), /* phase length */
U8X8_CA(0x0b1, 0x051), /* phase length */
//U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
U8X8_CA(0x0b3, 0x001), /* set display clock divide ratio/oscillator frequency */
//? U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
//? U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
U8X8_C(0x0b9), /* use linear lookup table */
//U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
U8X8_CA(0x0bc, 0x008), /* pre-charge voltage level */
//U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
U8X8_CA(0x0be, 0x007), /* VCOMH voltage */
U8X8_CA(0x0b6, 0x001), /* second precharge */
U8X8_CA(0x0d5, 0x062), /* enable second precharge, internal vsl (bit0 = 0) */
U8X8_C(0x0a4), /* normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1327_ea_w128128_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x051), /* remap configuration */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1327_ea_w128128_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x042), /* remap configuration */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1327_ea_w128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_ea_w128128_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ea_w128128_init_seq);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
{
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ea_w128128_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_ea_w128128_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
return 1;
}
return 0;
}
/*=============================================*/
/* MIDAS MCOT128128C1V-YM 128x128 Module */
static const u8x8_display_info_t u8x8_ssd1327_128x128_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 10,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100, /**/
/* sda_setup_time_ns = */ 100, /* */
/* sck_pulse_width_ns = */ 100, /* */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 1, /* use 1 instead of 4, because the SSD1327 seems to be very slow */
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 60,
/* tile_width = */ 16,
/* tile_hight = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 128
};
/* https://github.com/SeeedDocument/Grove_OLED_1.12/raw/master/resources/LY120-096096.pdf */
/* http://www.seeedstudio.com/wiki/index.php?title=Twig_-_OLED_96x96 */
/* values from u8glib */
/*
Re-map setting in Graphic Display Data RAM, command 0x0a0
Bit 0: Column Address Re-map
Bit 1: Nibble Re-map
Bit 2: Horizontal/Vertical Address Increment
Bit 3: Not used, must be 0
Bit 4: COM Re-map
Bit 5: Not used, must be 0
Bit 6: COM Split Odd Even
Bit 7: Not used, must be 0
*/
static const uint8_t u8x8_d_ssd1327_128x128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0fd, 0x012), /* unlock display, usually not required because the display is unlocked after reset */
U8X8_C(0x0ae), /* display off */
//U8X8_CA(0x0a8, 0x03f), /* multiplex ratio: 0x03f * 1/64 duty */
//U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x05f * 1/64 duty */
U8X8_CA(0x0a8, 0x07f), /* multiplex ratio: 0x05f * 1/128duty */
U8X8_CA(0x0a1, 0x000), /* display start line */
//U8X8_CA(0x0a2, 0x04c), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x051), /* remap configuration */
U8X8_CA(0x0ab, 0x001), /* Enable internal VDD regulator (RESET) */
//U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */
U8X8_CA(0x081, 0x053), /* contrast, brightness, 0..128 */
//U8X8_CA(0x0b1, 0x055), /* phase length */
U8X8_CA(0x0b1, 0x051), /* phase length */
//U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
U8X8_CA(0x0b3, 0x001), /* set display clock divide ratio/oscillator frequency */
//? U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
//? U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
U8X8_C(0x0b9), /* use linear lookup table */
//U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
U8X8_CA(0x0bc, 0x008), /* pre-charge voltage level */
//U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
U8X8_CA(0x0be, 0x007), /* VCOMH voltage */
U8X8_CA(0x0b6, 0x001), /* second precharge */
U8X8_CA(0x0d5, 0x062), /* enable second precharge, internal vsl (bit0 = 0) */
U8X8_C(0x0a4), /* normal display mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1327_128x128_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x051), /* remap configuration */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1327_128x128_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a0, 0x042), /* remap configuration */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1327_midas_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call the 96x96 procedure at the moment */
if ( u8x8_d_ssd1327_96x96_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1327_128x128_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_init_seq);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
{
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1327_128x128_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
return 1;
}
return 0;
}

View File

@ -0,0 +1,298 @@
/*
u8x8_d_ssd1329.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_ssd1329_128x96_noname_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_CA(0x0b3, 0x091), /* set display clock divide ratio/oscillator frequency (set clock as 135 frames/sec) */
U8X8_CA(0x0a8, 0x05f), /* multiplex ratio: 0x03f * 1/64 duty - changed by CREESOO, acc. to datasheet, 100317*/
U8X8_CA(0x0a2, 0x000), /* display offset, shift mapping ram counter */
U8X8_CA(0x0a1, 0x000), /* display start line */
U8X8_CA(0x0ad, 0x002), /* master configuration: disable embedded DC-DC, enable internal VCOMH */
U8X8_CA(0x0a0, 0x052), /* remap configuration, horizontal address increment (bit 2 = 0), enable nibble remap (upper nibble is left, bit 1 = 1) */
U8X8_C(0x086), /* full current range (0x084, 0x085, 0x086) */
#ifdef removed
U8X8_C(0x0b8), /* set gray scale table */
U8X8_A(1), /* */
U8X8_A(5), /* */
U8X8_A(10), /* */
U8X8_A(14), /* */
U8X8_A(19), /* */
U8X8_A(23), /* */
U8X8_A(28), /* */
U8X8_A(32), /* */
U8X8_A(37), /* */
U8X8_A(41), /* */
U8X8_A(46), /* */
U8X8_A(50), /* */
U8X8_A(55), /* */
U8X8_A(59), /* */
U8X8_A(63), /* */
#endif
U8X8_C(0x0b7), /* set default gray scale table */
U8X8_CA(0x081, 0x070), /* contrast, brightness, 0..128 */
U8X8_CA(0x0b2, 0x051), /* frame frequency (row period) */
U8X8_CA(0x0b1, 0x055), /* phase length */
U8X8_CA(0x0bc, 0x010), /* pre-charge voltage level */
U8X8_CA(0x0b4, 0x002), /* set pre-charge compensation level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_CA(0x0b0, 0x028), /* enable pre-charge compensation (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_CA(0x0be, 0x01c), /* VCOMH voltage */
U8X8_CA(0x0bf, 0x002|0x00d), /* VSL voltage level (not documented in the SDD1325 datasheet, but used in the NHD init seq.) */
U8X8_C(0x0a4), /* normal display mode */
U8X8_CA(0x023, 0x003), /* graphics accelleration: fill pixel */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1329_128x96_nhd_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1329_128x96_nhd_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1329_128x96_nhd_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a0, 0x052), /* remap */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1329_128x96_nhd_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0a0, 0x041), /* remap */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/*
input:
one tile (8 Bytes)
output:
Tile for ssd1329 (32 Bytes)
*/
static uint8_t u8x8_ssd1329_8to32_dest_buf[32];
static uint8_t *u8x8_ssd1329_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
{
uint8_t v;
uint8_t a,b;
uint8_t i, j;
uint8_t *dest;
for( j = 0; j < 4; j++ )
{
dest = u8x8_ssd1329_8to32_dest_buf;
dest += j;
a =*ptr;
ptr++;
b = *ptr;
ptr++;
for( i = 0; i < 8; i++ )
{
v = 0;
if ( a&1 ) v |= 0xf0;
if ( b&1 ) v |= 0x0f;
*dest = v;
dest+=4;
a >>= 1;
b >>= 1;
}
}
return u8x8_ssd1329_8to32_dest_buf;
}
static uint8_t u8x8_d_ssd1329_128x96_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1329_128x96_nhd_display_info);
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_noname_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_nhd_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_nhd_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_nhd_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1329_128x96_nhd_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* ssd1329 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 4;
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y *= 8;
y += u8x8->x_offset; /* x_offset is used as y offset for the ssd1329 */
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
if ( ptr[0] | ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] | ptr[7] )
{
/* draw the tile if pattern is not zero for all bytes */
u8x8_cad_SendCmd(u8x8, 0x015 ); /* set column address */
u8x8_cad_SendArg(u8x8, x ); /* start */
u8x8_cad_SendArg(u8x8, x+3 ); /* end */
u8x8_cad_SendCmd(u8x8, 0x075 ); /* set row address */
u8x8_cad_SendArg(u8x8, y);
u8x8_cad_SendArg(u8x8, y+7);
u8x8_cad_SendData(u8x8, 32, u8x8_ssd1329_8to32(u8x8, ptr));
}
else
{
/* tile is empty, use the graphics acceleration command */
/* are this really available on the SSD1329??? */
u8x8_cad_SendCmd(u8x8, 0x024 ); // draw rectangle
u8x8_cad_SendArg(u8x8, x );
u8x8_cad_SendArg(u8x8, y );
u8x8_cad_SendArg(u8x8, x+3 );
u8x8_cad_SendArg(u8x8, y+7 );
u8x8_cad_SendArg(u8x8, 0 ); // clear
}
ptr += 8;
x += 4;
c--;
} while( c > 0 );
//x += 4;
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1329_128x96_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 15,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100, /**/
/* sda_setup_time_ns = */ 100, /* ssd1329 */
/* sck_pulse_width_ns = */ 100, /* ssd1329 */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 60, /* ssd1329 */
/* tile_width = */ 16,
/* tile_hight = */ 12,
/* default_x_offset = */ 0, /* x_offset is used as y offset for the ssd1329 */
/* flipmode_x_offset = */ 0, /* x_offset is used as y offset for the ssd1329 */
/* pixel_width = */ 128,
/* pixel_height = */ 96
};
uint8_t u8x8_d_ssd1329_128x96_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1329_128x96_display_info);
return 1;
}
return u8x8_d_ssd1329_128x96_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,394 @@
/*
u8x8_d_ssd1606_172x72.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SSD1606: 128x180x2
two-bit, four graylevels
command
0x22: assign actions
0x20: execute actions
action for command 0x022 are (more or less guessed)
bit 7: Enable Clock
bit 6: Enable Charge Pump
bit 5: Load Temparture Value (???)
bit 4: Load LUT (???)
bit 3: Initial Display (???)
bit 2: Pattern Display --> Requires about 945ms with the LUT from below
bit 1: Disable Charge Pump
bit 0: Disable Clock
Disable Charge Pump and Clock require about 267ms
Enable Charge Pump and Clock require about 10ms
Notes:
- Introduced a refresh display message, which copies RAM to display
- Charge pump and clock are only enabled for the transfer RAM to display
- U8x8 will not really work because of the two buffers in the SSD1606, however U8g2 should be ok.
*/
#include "u8x8.h"
#define L(a,b,c,d) (((a)<<6)|((b)<<4)|((c)<<2)|(d))
/* GDE021A1, 2.1" EPD */
static const uint8_t u8x8_d_ssd1606_172x72_gde021a1_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: Disable */
U8X8_CA(0x11, 0x03), /* Define data entry mode, x&y inc, x first */
U8X8_CAA(0x44, 0, 31), /* RAM x start & end, each byte has 4 pixel, 32*4=128 */
U8X8_CAA(0x45, 0, 179), /* RAM y start & end, 179 MAX */
U8X8_CA(0x4e, 0), /* set x pos, 0..31 */
U8X8_CA(0x4f, 0), /* set y pos, 0...179 */
U8X8_CA(0xf0, 0x1f), /* set booster feedback to internal */
U8X8_CA(0x22, 0xc0), /* display update seq. option: enable clk, enable CP, .... todo: this is never activated */
U8X8_C(0x32), /* write LUT register*/
#ifdef ORIGINAL_LUT
/* wavefrom part of the LUT: absolute LUT... this will always force the destination color */
U8X8_A4(0x00,0x00,0x00,0x55), /* step 0 */
U8X8_A4(0x00,0x00,0x55,0x55), /* step 1 */
U8X8_A4(0x00,0x55,0x55,0x55),
U8X8_A4(0xAA,0xAA,0xAA,0xAA),
U8X8_A4(0x15,0x15,0x15,0x15),
U8X8_A4(0x05,0x05,0x05,0x05),
U8X8_A4(0x01,0x01,0x01,0x01),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00), /* step 19 */
/* timing part of the LUT */
U8X8_A8(0x22,0xFB,0x22,0x1B,0x00,0x00,0x00,0x00),
U8X8_A(0x00),U8X8_A(0x00),
#else
/* the following LUT will not change anything if the old and the new values are the same */
/* 03 02 01 00 13 12 11 10 23 22 21 20 33 32 31 30 original */
U8X8_A4(L(0, 0, 0, 0), L(0, 0, 0, 0), L(0, 0, 0, 0), L(0, 1, 1, 1)), // 0x00,0x00,0x00,0x55, step 0
U8X8_A4(L(0, 0, 0, 0), L(0, 0, 0, 0), L(1, 0, 1, 1), L(0, 1, 1, 1)), // 0x00,0x00,0x55,0x55, step 1
U8X8_A4(L(0, 0, 0, 0), L(1, 1, 0, 1), L(1, 0, 1, 1), L(0, 1, 1, 1)), // 0x00,0x55,0x55,0x55, step 2
U8X8_A4(L(2, 2, 2, 0), L(2, 2, 0, 2), L(2, 0, 2, 2), L(0, 2, 2, 2)), // 0xAA,0xAA,0xAA,0xAA, step 3
U8X8_A4(L(0, 1, 1, 0), L(0, 1, 0, 1), L(0, 0, 1, 1), L(0, 1, 1, 1)), // 0x15,0x15,0x15,0x15, step 4
U8X8_A4(L(0, 0, 1, 0), L(0, 0, 0, 1), L(0, 0, 1, 1), L(0, 0, 1, 1)), // 0x05,0x05,0x05,0x05, step 5
U8X8_A4(L(0, 0, 0, 0), L(0, 0, 0, 1), L(0, 0, 0, 1), L(0, 0, 0, 1)), // 0x01,0x01,0x01,0x01, step 6
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00),
U8X8_A4(0x00,0x00,0x00,0x00), /* step 19 */
/* timing part of the LUT */
U8X8_A8(0x22,0xFB,0x22,0x1B,0x00,0x00,0x00,0x00),
U8X8_A(0x00),U8X8_A(0x00),
#endif
U8X8_CA(0x2c, 0xa0), /* write vcom value*/
U8X8_CA(0x3c, 0x63), /* select boarder waveform */
U8X8_CA(0x22, 0xc4), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
/* 0x0c4 is mentioned in chapter 9.2 of the GDE021A1 data sheet */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1606_to_display_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
//U8X8_CA(0x22, 0xc0), /* display update seq. option: Enable clock and charge pump */
//U8X8_C(0x20), /* execute sequence */
//U8X8_DLY(10),
/* strange, splitting 0x0c0 does not work reliable */
U8X8_CA(0x22, 0xc4), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(250), /* the sequence above requires about 970ms */
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(230),
U8X8_CA(0x22, 0x03), /* disable clock and charge pump */
U8X8_DLY(200), /* this requres about 270ms */
U8X8_DLY(90),
//U8X8_CA(0x10, 0x01), /* deep sleep mode */
//U8X8_C(0x20), /* execute sequence */
U8X8_DLY(50),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
// static const uint8_t u8x8_d_ssd1606_172x72_powersave0_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
// static const uint8_t u8x8_d_ssd1606_172x72_powersave1_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
// static const uint8_t u8x8_d_ssd1606_172x72_flip0_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
// static const uint8_t u8x8_d_ssd1606_172x72_flip1_seq[] = {
// U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
// U8X8_END_TRANSFER(), /* disable chip */
// U8X8_END() /* end of sequence */
// };
static uint8_t *u8x8_convert_tile_for_ssd1606(uint8_t *t)
{
uint8_t i;
uint16_t r;
static uint8_t buf[16];
uint8_t *pbuf = buf;
for( i = 0; i < 8; i++ )
{
r = u8x8_upscale_byte(~(*t++));
*pbuf++ = (r>>8) & 255;
*pbuf++ = r & 255;
}
return buf;
}
static void u8x8_d_ssd1606_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
static void u8x8_d_ssd1606_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c, page;
uint8_t *ptr;
u8x8_cad_StartTransfer(u8x8);
page = u8x8->display_info->tile_height;
page --;
page -= (((u8x8_tile_t *)arg_ptr)->y_pos);
page *= 2;
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x00f ); /* scan start */
u8x8_cad_SendArg(u8x8, 0);
u8x8_cad_SendCmd(u8x8, 0x011 ); /* cursor increment mode */
u8x8_cad_SendArg(u8x8, 3);
u8x8_cad_SendCmd(u8x8, 0x045 ); /* window start column */
u8x8_cad_SendArg(u8x8, 0);
u8x8_cad_SendArg(u8x8, 179); /* end of display */
u8x8_cad_SendCmd(u8x8, 0x044 ); /* window end page */
u8x8_cad_SendArg(u8x8, page);
u8x8_cad_SendArg(u8x8, page+1);
u8x8_cad_SendCmd(u8x8, 0x04f ); /* window column */
u8x8_cad_SendArg(u8x8, x);
u8x8_cad_SendCmd(u8x8, 0x04e ); /* window row */
u8x8_cad_SendArg(u8x8, page);
u8x8_cad_SendCmd(u8x8, 0x024 );
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, 16, u8x8_convert_tile_for_ssd1606(ptr));
ptr += 8;
x += 8;
c--;
} while( c > 0 );
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
}
static uint8_t u8x8_d_ssd1606_172x72_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1606_172x72_display_info);
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_gde021a1_init_seq);
/* special code for the SSD1606... */
/* ensure that the initial buffer is clear and all eInk is set to white */
/* this is done here, because the LUT will be of that kind, that it uses the previous color */
/* make everything black */
u8x8_FillDisplay(u8x8);
/* write content to the display */
u8x8_RefreshDisplay(u8x8);
/* now make everything clear */
u8x8_FillDisplay(u8x8);
/* write content to the display */
u8x8_RefreshDisplay(u8x8);
/* now make everything clear */
u8x8_ClearDisplay(u8x8);
/* write content to the display */
u8x8_RefreshDisplay(u8x8);
u8x8_ClearDisplay(u8x8);
/* write content to the display */
u8x8_RefreshDisplay(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
/*
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_powersave1_seq);
*/
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
/*
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_172x72_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
*/
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
/*
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_EndTransfer(u8x8);
*/
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_d_ssd1606_draw_tile(u8x8, arg_int, arg_ptr);
break;
case U8X8_MSG_DISPLAY_REFRESH:
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1606_to_display_seq);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_ssd1606_172x72_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 120,
/* pre_chip_disable_wait_ns = */ 60,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 50, /* SSD1606: */
/* sck_pulse_width_ns = */ 100, /* SSD1606: 100ns */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150,
/* tile_width = */ 22, /* 22*8 = 176 */
/* tile_hight = */ 9, /* 9*8 = 72 */
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 172,
/* pixel_height = */ 72
};
uint8_t u8x8_d_ssd1606_172x72(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1606_172x72_display_info);
return 1;
}
return u8x8_d_ssd1606_172x72_generic(u8x8, msg, arg_int, arg_ptr);
}

View File

@ -0,0 +1,597 @@
/*
u8x8_d_ssd1607_200x200.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SSD1607: 200x300x1
command
0x22: assign actions
0x20: execute actions
action for command 0x022 are (more or less guessed)
bit 7: Enable Clock
bit 6: Enable Charge Pump
bit 5: Load Temparture Value (???)
bit 4: Load LUT (???)
bit 3: Initial Display (???)
bit 2: Pattern Display --> Requires about 945ms with the LUT from below
bit 1: Disable Charge Pump
bit 0: Disable Clock
Disable Charge Pump and Clock require about 267ms
Enable Charge Pump and Clock require about 10ms
Notes:
- Introduced a refresh display message, which copies RAM to display
- Charge pump and clock are only enabled for the transfer RAM to display
- U8x8 will not really work because of the two buffers in the SSD1606, however U8g2 should be ok.
*/
#include "u8x8.h"
/*=================================================*/
static const u8x8_display_info_t u8x8_ssd1607_200x200_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* values from SSD1606 */
/* post_chip_enable_wait_ns = */ 120,
/* pre_chip_disable_wait_ns = */ 60,
/* reset_pulse_width_ms = */ 100,
/* post_reset_wait_ms = */ 100,
/* sda_setup_time_ns = */ 50, /* SSD1606: */
/* sck_pulse_width_ns = */ 100, /* SSD1606: 100ns */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 2, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40,
/* write_pulse_width_ns = */ 150,
/* tile_width = */ 25, /* 25*8 = 200 */
/* tile_hight = */ 25,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 200,
/* pixel_height = */ 200
};
static const uint8_t u8x8_d_ssd1607_200x200_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x22, 0xc0), /* enable clock and charge pump */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(200), /* according to my measures it may take up to 150ms */
U8X8_DLY(100), /* but it might take longer */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1607_200x200_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
/* disable clock and charge pump only, deep sleep is not entered, because we will loose RAM content */
U8X8_CA(0x22, 0x02), /* only disable charge pump, HW reset seems to be required if the clock is disabled */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(20),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1607_200x200_exec_1000dly_seq[] = {
// assumes, that the start transfer has happend
U8X8_CA(0x22, 0x04), /* display update seq. option: pattern display */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static void u8x8_d_ssd1607_200x200_first_init(u8x8_t *u8x8)
{
u8x8_ClearDisplay(u8x8);
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x032); // program update sequence
u8x8_cad_SendMultipleArg(u8x8, 8, 0x055); // all black
u8x8_cad_SendMultipleArg(u8x8, 12, 0x0aa); // all white
u8x8_cad_SendMultipleArg(u8x8, 10, 0x022); // 830ms
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_exec_1000dly_seq);
}
static uint8_t *u8x8_convert_tile_for_ssd1607(uint8_t *t)
{
uint8_t i;
static uint8_t buf[8];
uint8_t *pbuf = buf;
for( i = 0; i < 8; i++ )
{
*pbuf++ = ~(*t++);
}
return buf;
}
static void u8x8_d_ssd1607_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr) U8X8_NOINLINE;
static void u8x8_d_ssd1607_draw_tile(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
{
uint16_t x;
uint8_t c, page;
uint8_t *ptr;
u8x8_cad_StartTransfer(u8x8);
page = u8x8->display_info->tile_height;
page --;
page -= (((u8x8_tile_t *)arg_ptr)->y_pos);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x045 ); /* window start column */
u8x8_cad_SendArg(u8x8, 0);
u8x8_cad_SendArg(u8x8, 0);
u8x8_cad_SendArg(u8x8, 199); /* end of display */
u8x8_cad_SendArg(u8x8, 0);
u8x8_cad_SendCmd(u8x8, 0x044 ); /* window end page */
u8x8_cad_SendArg(u8x8, page);
u8x8_cad_SendArg(u8x8, page);
u8x8_cad_SendCmd(u8x8, 0x04f ); /* window column */
u8x8_cad_SendArg(u8x8, x&255);
u8x8_cad_SendArg(u8x8, x>>8);
u8x8_cad_SendCmd(u8x8, 0x04e ); /* window row */
u8x8_cad_SendArg(u8x8, page);
u8x8_cad_SendCmd(u8x8, 0x024 );
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, 8, u8x8_convert_tile_for_ssd1607(ptr));
ptr += 8;
x += 8;
c--;
} while( c > 0 );
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
}
/*=================================================*/
#define L(a,b,c,d) (((a)<<6)|((b)<<4)|((c)<<2)|(d))
/* https://github.com/embeddedadventures/SSD1607/blob/master/SSD1607.cpp */
static const uint8_t u8x8_d_ssd1607_200x200_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
//U8X8_CA(0x10, 0x00), /* Deep Sleep mode Control: Disable */
U8X8_C(0x01),
U8X8_A(199),U8X8_A(0),U8X8_A(0),
U8X8_CA(0x03, 0x00), /* Gate Driving voltage: 15V (lowest value)*/
U8X8_CA(0x04, 0x0a), /* Source Driving voltage: 15V (mid value and POR)*/
U8X8_CA(0x0f, 0x00), /* scan start ? */
U8X8_CA(0xf0, 0x1f), /* set booster feedback to internal */
U8X8_CA(0x2c, 0xa8), /* write vcom value*/
U8X8_CA(0x3a, 0x1a), /* dummy lines */
U8X8_CA(0x3b, 0x08), /* gate time */
U8X8_CA(0x3c, 0x33), /* select boarder waveform */
U8X8_CA(0x11, 0x03), /* cursor increment mode */
U8X8_CAA(0x44, 0, 24), /* RAM x start & end, each byte has 8 pixel, 25*4=200 */
U8X8_CAAAA(0x45, 0, 0, 299&255, 299>>8), /* RAM y start & end, 0..299 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_ssd1607_to_display_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x32), /* write LUT register*/
/* according to the command table, the lut has 240 bits (=30 bytes * 8 bits) */
/* Waveform part of the LUT (20 bytes) */
/* bit 7/6: 1 - 1 transition */
/* bit 5/4: 1 - 0 transition */
/* bit 3/2: 0 - 1 transition */
/* bit 1/0: 0 - 0 transition */
/* 00 VSS */
/* 01 VSH */
/* 10 VSL */
/* 11 NA */
/* original values */
/*
U8X8_A(0x02),
U8X8_A(0x02),
U8X8_A(0x01),
U8X8_A(0x11),
U8X8_A(0x12),
U8X8_A(0x12),
U8X8_A(0x22),
U8X8_A(0x22),
U8X8_A(0x66),
U8X8_A(0x69),
U8X8_A(0x69),
U8X8_A(0x59),
U8X8_A(0x58),
U8X8_A(0x99),
U8X8_A(0x99),
U8X8_A(0x88),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
*/
/* original values, L-macro */
U8X8_A(L(0,0,0,2)), // 0x02
U8X8_A(L(0,0,0,2)), // 0x02
U8X8_A(L(0,0,0,1)), // 0x01
U8X8_A(L(0,1,0,1)), // 0x11
U8X8_A(L(0,1,0,2)), // 0x12
U8X8_A(L(0,1,0,2)), // 0x12
U8X8_A(L(0,2,0,2)), // 0x22
U8X8_A(L(0,2,0,2)), // 0x22
U8X8_A(L(1,2,1,2)), // 0x66
U8X8_A(L(1,2,2,1)), // 0x69
U8X8_A(L(1,2,2,1)), // 0x69
U8X8_A(L(1,1,2,1)), // 0x59
U8X8_A(L(1,1,2,0)), // 0x58
U8X8_A(L(2,1,2,1)), // 0x99
U8X8_A(L(2,1,2,1)), // 0x99
U8X8_A(L(2,0,2,0)), // 0x88
U8X8_A(L(0,0,0,0)), // 0x00
U8X8_A(L(0,0,0,0)), // 0x00
U8X8_A(L(0,0,0,0)), // 0x00
U8X8_A(L(0,0,0,0)), // 0x00
/* orginal values without 0-0 and 1-1 transition */
/*
U8X8_A(L(3,0,0,3)), // 0x02
U8X8_A(L(3,0,0,3)), // 0x02
U8X8_A(L(3,0,0,3)), // 0x01
U8X8_A(L(3,1,0,3)), // 0x11
U8X8_A(L(3,1,0,3)), // 0x12
U8X8_A(L(3,1,0,3)), // 0x12
U8X8_A(L(3,2,0,3)), // 0x22
U8X8_A(L(3,2,0,3)), // 0x22
U8X8_A(L(3,2,1,3)), // 0x66
U8X8_A(L(3,2,2,3)), // 0x69
U8X8_A(L(3,2,2,3)), // 0x69
U8X8_A(L(3,1,2,3)), // 0x59
U8X8_A(L(3,1,2,3)), // 0x58
U8X8_A(L(3,1,2,3)), // 0x99
U8X8_A(L(3,1,2,3)), // 0x99
U8X8_A(L(3,0,2,3)), // 0x88
U8X8_A(L(3,0,0,3)), // 0x00
U8X8_A(L(3,0,0,3)), // 0x00
U8X8_A(L(3,0,0,3)), // 0x00
U8X8_A(L(3,0,0,3)), // 0x00
*/
/* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */
U8X8_A(0xF8),
U8X8_A(0xB4),
U8X8_A(0x13),
U8X8_A(0x51),
U8X8_A(0x35),
U8X8_A(0x51),
U8X8_A(0x51),
U8X8_A(0x19),
U8X8_A(0x01),
U8X8_A(0x00),
U8X8_CA(0x22, 0x04), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(250), /* the sequence above requires about 1200ms for the 200x200 display*/
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1607_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_init_seq);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
u8x8_d_ssd1607_200x200_first_init(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr);
break;
case U8X8_MSG_DISPLAY_REFRESH:
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_to_display_seq);
break;
default:
return 0;
}
return 1;
}
/*=================================================*/
/* there is no improvement possible... so i consider the v2 version as obsolete */
static const uint8_t u8x8_d_ssd1607_v2_to_display_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
/*
0xaa, 0x09, 0x09, 0x19, 0x19,
0x11, 0x11, 0x11, 0x11, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x77, 0x77, 0x77, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00
measured 1240 ms with IL3830 196x128
0x02, 0x02, 0x01, 0x11, 0x12,
0x12, 0x12, 0x22, 0x22, 0x66,
0x69, 0x59, 0x58, 0x99, 0x99,
0x88, 0x00, 0x00, 0x00, 0x00,
0xf8, 0xb4, 0x13, 0x51, 0x35,
0x51, 0x51, 0xe9, 0x04, 0x00
*/
U8X8_C(0x32), /* write LUT register*/
/* https://github.com/olikraus/u8g2/issues/347 */
U8X8_A(0x02),
U8X8_A(0x02),
U8X8_A(0x01),
U8X8_A(0x11),
U8X8_A(0x12),
U8X8_A(0x12),
U8X8_A(0x22),
U8X8_A(0x22),
U8X8_A(0x66),
U8X8_A(0x69),
U8X8_A(0x69),
U8X8_A(0x59),
U8X8_A(0x58),
U8X8_A(0x99),
U8X8_A(0x99),
U8X8_A(0x88),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
U8X8_A(0x00),
/* Timing part of the LUT, 20 Phases with 4 bit each: 10 bytes */
U8X8_A(0xF8),
U8X8_A(0xB4),
U8X8_A(0x13),
U8X8_A(0x51),
U8X8_A(0x35),
U8X8_A(0x51),
U8X8_A(0x51),
U8X8_A(0xe9),
U8X8_A(0x04),
U8X8_A(0x00),
U8X8_CA(0x22, 0x04), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(250), /* delay for 1500ms. The current sequence takes 1300ms */
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1607_v2_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_init_seq);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
u8x8_d_ssd1607_200x200_first_init(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr);
break;
case U8X8_MSG_DISPLAY_REFRESH:
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_v2_to_display_seq);
break;
default:
return 0;
}
return 1;
}
/*=================================================*/
/* GDEP015OC1 */
/* https://github.com/olikraus/u8g2/issues/454 */
static const uint8_t u8x8_d_ssd1607_gd_to_display_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
/*
0xaa, 0x09, 0x09, 0x19, 0x19,
0x11, 0x11, 0x11, 0x11, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x77, 0x77, 0x77, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00
measured 1240 ms with IL3830 196x128
0x02, 0x02, 0x01, 0x11, 0x12,
0x12, 0x12, 0x22, 0x22, 0x66,
0x69, 0x59, 0x58, 0x99, 0x99,
0x88, 0x00, 0x00, 0x00, 0x00,
0xf8, 0xb4, 0x13, 0x51, 0x35,
0x51, 0x51, 0xe9, 0x04, 0x00
*/
U8X8_C(0x32), /* write LUT register*/
U8X8_A(0x50), U8X8_A(0xAA), U8X8_A(0x55), U8X8_A(0xAA), U8X8_A(0x11),
U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00),
U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00),
U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00),
U8X8_A(0xFF), U8X8_A(0xFF), U8X8_A(0x1F), U8X8_A(0x00), U8X8_A(0x00),
U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00), U8X8_A(0x00),
U8X8_CA(0x22, 0x04), /* display update seq. option: clk -> CP -> LUT -> initial display -> pattern display */
U8X8_C(0x20), /* execute sequence */
U8X8_DLY(250), /* delay for 1500ms. The current sequence takes 1300ms */
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_DLY(250),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_ssd1607_gd_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1607_200x200_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_init_seq);
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
u8x8_d_ssd1607_200x200_first_init(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_200x200_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_d_ssd1607_draw_tile(u8x8, arg_int, arg_ptr);
break;
case U8X8_MSG_DISPLAY_REFRESH:
u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1607_gd_to_display_seq);
break;
default:
return 0;
}
return 1;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,711 @@
/*
u8x8_d_st7567.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_st7567_132x64_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a4), /* all pixel off, issue 142 */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7567_132x64_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7567_132x64_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7567_132x64_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7567_n_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7567_n_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/*=====================================================*/
static const u8x8_display_info_t u8x8_st7567_132x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 150, /* */
/* pre_chip_disable_wait_ns = */ 50, /* */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 1,
/* sda_setup_time_ns = */ 50, /* */
/* sck_pulse_width_ns = */ 120, /* */
/* sck_clock_hz = */ 4000000UL, /* */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40, /* */
/* write_pulse_width_ns = */ 80, /* */
/* tile_width = */ 17, /* width of 17*8=136 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 132,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_st7567_132x64_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x0a1), /* ADC set to reverse */
U8X8_C(0x0c0), /* common output mode */
// Flipmode
//U8X8_C(0x0a0), /* ADC set to reverse */
//U8X8_C(0x0c8), /* common output mode */
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
U8X8_C(0x0a3), /* LCD bias 1/7 */
/* power on sequence from paxinstruments */
U8X8_C(0x028|4), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|6), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|7), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x026), /* v0 voltage resistor ratio */
U8X8_CA(0x081, 0x027), /* set contrast, contrast value*/
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* pax instruments 132x64 display */
uint8_t u8x8_d_st7567_pi_132x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_132x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
/*
The following if condition checks the hardware limits of the st7567
controller: It is not allowed to write beyond the display limits.
This is in fact an issue within flip mode.
*/
if ( c + x > 132u )
{
c = 132u;
c -= x;
}
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*=====================================================*/
static const u8x8_display_info_t u8x8_st7567_jlx12864_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 150, /* */
/* pre_chip_disable_wait_ns = */ 50, /* */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 1,
/* sda_setup_time_ns = */ 50, /* */
/* sck_pulse_width_ns = */ 120, /* */
/* sck_clock_hz = */ 4000000UL, /* */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40, /* */
/* write_pulse_width_ns = */ 80, /* */
/* tile_width = */ 16, /* width of 16*8=128 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 4,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static const uint8_t u8x8_st7567_jlx12864_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x0a1), /* ADC set to reverse */
U8X8_C(0x0c0), /* common output mode */
// Flipmode
//U8X8_C(0x0a0), /* ADC set to reverse */
//U8X8_C(0x0c8), /* common output mode */
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
U8X8_C(0x0a3), /* LCD bias 1/7 */
/* power on sequence from paxinstruments */
U8X8_C(0x028|4), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|6), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|7), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x023), /* v0 voltage resistor ratio */
U8X8_CA(0x081, 42>>2), /* set contrast, contrast value*/
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* JLX12864 display */
uint8_t u8x8_d_st7567_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_jlx12864_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_st7567_jlx12864_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
/*
The following if condition checks the hardware limits of the st7567
controller: It is not allowed to write beyond the display limits.
This is in fact an issue within flip mode.
*/
if ( c + x > 132u )
{
c = 132u;
c -= x;
}
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*=====================================================*/
static const u8x8_display_info_t u8x8_st7567_enh_dg128064_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 150, /* */
/* pre_chip_disable_wait_ns = */ 50, /* */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 1,
/* sda_setup_time_ns = */ 50, /* */
/* sck_pulse_width_ns = */ 120, /* */
/* sck_clock_hz = */ 4000000UL, /* */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40, /* */
/* write_pulse_width_ns = */ 80, /* */
/* tile_width = */ 16, /* width of 16*8=128 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 4,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static const u8x8_display_info_t u8x8_st7567_enh_dg128064i_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 150, /* */
/* pre_chip_disable_wait_ns = */ 50, /* */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 1,
/* sda_setup_time_ns = */ 50, /* */
/* sck_pulse_width_ns = */ 120, /* */
/* sck_clock_hz = */ 4000000UL, /* */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40, /* */
/* write_pulse_width_ns = */ 80, /* */
/* tile_width = */ 16, /* width of 16*8=128 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 4,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static const uint8_t u8x8_st7567_enh_dg128064_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x0a1), /* ADC set to reverse */
U8X8_C(0x0c0), /* common output mode */
// Flipmode
//U8X8_C(0x0a0), /* ADC set to reverse */
//U8X8_C(0x0c8), /* common output mode */
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
U8X8_C(0x0a2), /* LCD bias 1/9 */
/* power on sequence from paxinstruments */
U8X8_C(0x028|4), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|6), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|7), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x023), /* v0 voltage resistor ratio */
U8X8_CA(0x081, 200>>2), /* set contrast, contrast value*/
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* ENH-DG128064 transparent display */
static uint8_t u8x8_d_st7567_enh_dg128064_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_enh_dg128064_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_st7567_enh_dg128064_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
/*
The following if condition checks the hardware limits of the st7567
controller: It is not allowed to write beyond the display limits.
This is in fact an issue within flip mode.
*/
if ( c + x > 132u )
{
c = 132u;
c -= x;
}
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
uint8_t u8x8_d_st7567_enh_dg128064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_enh_dg128064_display_info);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_n_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_n_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
default:
return u8x8_d_st7567_enh_dg128064_generic(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
uint8_t u8x8_d_st7567_enh_dg128064i(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_enh_dg128064i_display_info);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
default:
return u8x8_d_st7567_enh_dg128064_generic(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
/*=====================================================*/
/* issue 657 */
static const u8x8_display_info_t u8x8_st7567_64x32_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 150, /* */
/* pre_chip_disable_wait_ns = */ 50, /* */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 1,
/* sda_setup_time_ns = */ 50, /* */
/* sck_pulse_width_ns = */ 120, /* */
/* sck_clock_hz = */ 4000000UL, /* */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 40, /* */
/* write_pulse_width_ns = */ 80, /* */
/* tile_width = */ 8,
/* tile_hight = */ 4,
/* default_x_offset = */ 32,
/* flipmode_x_offset = */ 32,
/* pixel_width = */ 64,
/* pixel_height = */ 32
};
static const uint8_t u8x8_st7567_64x32_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x0a1), /* ADC */
U8X8_C(0x0c0), /* common output mode */
// Flipmode
//U8X8_C(0x0a0), /* ADC */
//U8X8_C(0x0c8), /* common output mode */
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
U8X8_C(0x0a2), /* LCD bias 1/9 */
U8X8_C(0x028|4), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|6), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x028|7), /* all power control circuits on */
U8X8_DLY(50),
U8X8_C(0x024), /* v0 voltage resistor ratio, taken from issue 657 */
U8X8_CA(0x081, 0x080), /* set contrast, contrast value*/
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_st7567_64x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7567_64x32_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_st7567_64x32_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_132x64_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* st7567 has range from 0 to 63 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
/*
The following if condition checks the hardware limits of the st7567
controller: It is not allowed to write beyond the display limits.
This is in fact an issue within flip mode.
*/
if ( c + x > 132u )
{
c = 132u;
c -= x;
}
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,253 @@
/*
u8x8_d_st7586s_erc240160.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
static const uint8_t u8x8_d_st7586s_sleep_on[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x010), /* set power save mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7586s_sleep_off[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x011), //Sleep out
U8X8_DLY(50), /* delay 50 ms */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7586s_erc240160_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x036), /* Scan Direction Setting */
U8X8_A(0x0C8), /* COM159 -> COM0 SEG383 -> SEG0 */
U8X8_C(0x037), /* Start line 0 */
U8X8_A(0x000),
U8X8_C(0x02A), /* Column Address Setting */
U8X8_A(0x000), /* COL8 -> COL127 */
U8X8_A(0x008),
U8X8_A(0x000),
U8X8_A(0x07F), /* 120*3=240 pixels + 120 unused */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7586s_erc240160_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x036), /* Scan Direction Setting */
U8X8_A(0x000), /* COM0 -> COM159 SEG0 -> SEG383 */
U8X8_C(0x037), /* Start line 0 */
U8X8_A(0x000),
U8X8_C(0x02A), /* Column Address Setting */
U8X8_A(0x000), /* COL0 -> COL119 */
U8X8_A(0x000),
U8X8_A(0x000),
U8X8_A(0x077), /* 120*3=240 pixels + 120 unused */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7586s_erc240160_init_seq[] = {
U8X8_END_TRANSFER(),/* disable chip */
// U8G_ESC_RST(1), /* hardware reset */
U8X8_DLY(60), /* Delay 60 ms */
U8X8_START_TRANSFER(),/* enable chip */
U8X8_C(0x001), // Soft reset
U8X8_DLY(60), // Delay 120 ms
U8X8_C(0x011), // Sleep Out
U8X8_C(0x028), // Display OFF
U8X8_DLY(25), // Delay 50 ms
U8X8_CAA(0x0C0,0x036,0x01),// Vop = 136h data sheet suggested 0x0145 but this caused streaks
U8X8_CA(0x0C3,0x000), // BIAS = 1/14
U8X8_CA(0x0C4,0x007), // Booster = x8
U8X8_CA(0x0D0,0x01D), // Enable Analog Circuit
U8X8_CA(0x0B3,0x000), // Set FOSC divider
U8X8_CA(0x0B5,0x000), // N-Line = 0
U8X8_C(0x039), // 0x39 Monochrome mode. 0x38 - gray Mode
U8X8_C(0x03A), // Enable DDRAM Interface
U8X8_A(0x002), // monochrome and 4-level
U8X8_C(0x036), // Scan Direction Setting
U8X8_A(0x0C8), // COM:C159->C0 SEG: SEG383->SEG0
U8X8_C(0x0B1), // First output COM
U8X8_A(0x000), //
U8X8_C(0x0B0), // Duty Setting (num rows - 1)
U8X8_A(0x09F),
U8X8_C(0x020), // Display inversion off
U8X8_C(0x02A), // Column Address Setting
U8X8_A(0x000), // COL0 -> COL127
U8X8_A(0x008), //
U8X8_A(0x000), //
U8X8_A(0x07F), // 80*3=240 pixels
U8X8_C(0x02B), // Row Address Setting
U8X8_A(0x000), // ROW0 -> ROW159
U8X8_A(0x000), //
U8X8_A(0x000), //
U8X8_A(0x09F), // 160 pixels
U8X8_C(0x029), // Display ON
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_st7586s_erc240160_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 5,
/* pre_chip_disable_wait_ns = */ 5,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 100, /* datasheet ST7586S */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* ST7586+Atmega128RFA1 works with 8MHz */
/* spi_mode = */ 3, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 20, /* datasheet suggests min 20 */
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 30,
/* tile_height = */ 20,
/* default_x_offset = */ 0, /* abused as flag to know if we are flipped */
/* flipmode_x_offset = */ 1, /* as pixel order different for normal/flipped */
/* pixel_width = */ 240,
/* pixel_height = */ 160
};
/*******************************************************************************
* st7586s_erc240160 driver. ST7586 based display from buydisplay.com
******************************************************************************/
uint8_t u8x8_d_st7586s_erc240160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
uint8_t c;
uint8_t *ptr;
uint8_t i, byte;
uint32_t input;
uint8_t output[4];
switch (msg) {
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8); // OK Start transfer
u8x8_cad_SendCmd(u8x8, 0x02B); /* Row Address Setting */
u8x8_cad_SendArg(u8x8, 0x000);
u8x8_cad_SendArg(u8x8, 0x008 * ((u8x8_tile_t *)arg_ptr)->y_pos);
u8x8_cad_SendArg(u8x8, 0x000);
u8x8_cad_SendArg(u8x8, 0x09F); // should set end row based on display dimensions
u8x8_cad_SendCmd(u8x8, 0x02C); /* cmd write display data to ram */
c = ((u8x8_tile_t *) arg_ptr)->cnt; //
c *= 8;
ptr = ((u8x8_tile_t *) arg_ptr)->tile_ptr; //
// The ST7586S has an unusual 3 pixels per byte format the ERC240160 is even more annoying
// as it has every 3rd COM line disconnected for extra oddness so here we read in a byte
// (8 pixels) and pack that into 4 bytes of 2 pixels + 1 unused each. This has to be done
// in a different order for flipped, normal UUx11x22 flipped 11x22xUU
while (c > 0) {
input = ((uint8_t)ptr[0]);
for (i=0; i<4; i++)
{
byte = 0;
if (u8x8->x_offset ==0){
if (input & 0x80) // if bit 7
byte = byte | 0x18; //set pixel 1
if (input & 0x40) // if bit 6
byte = byte | 0x3; //set pixel 2
}
if (u8x8->x_offset ==1){
if (input & 0x80) // if bit 7
byte = byte | 0xC0; //set pixel 1
if (input & 0x40) // if bit 6
byte = byte | 0x18; //set pixel 2
}
output[i] = byte;
input <<= 2;
}
u8x8_cad_SendData(u8x8, 4, output);
ptr += 1;
c -= 1;
}
u8x8_cad_EndTransfer(u8x8);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_erc240160_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7586s_erc240160_display_info);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_erc240160_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_erc240160_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if (arg_int == 0)
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_off);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_on);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x0C0);
u8x8_cad_SendArg(u8x8, arg_int);
u8x8_cad_SendArg(u8x8, 1);
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,246 @@
/*
u8x8_d_st7586s_s028hn118a.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2018, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g2.h"
static const uint8_t u8x8_d_st7586s_sleep_on[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x010), /* set power save mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7586s_sleep_off[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x011), //Sleep out
U8X8_DLY(50), /* delay 50 ms */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7586s_s028hn118a_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x036), /* Scan Direction Setting */
U8X8_A(0x000), /* COM0 -> COM159 SEG0 -> SEG384 */
U8X8_C(0x037), /* Start line 0 */
U8X8_A(0x000),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7586s_s028hn118a_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x036), /* Scan Direction Setting */
U8X8_A(0x0C8), /* COM159 -> COM0 SEG384 -> SEG0 */
U8X8_C(0x037), /* Start line 24 */
U8X8_A(0x018),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_st7586s_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
uint8_t c;
uint8_t *ptr;
uint8_t i, byte;
uint32_t input;
uint8_t output[8];
switch (msg) {
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8); // OK Start transfer
u8x8_cad_SendCmd(u8x8, 0x02B); /* Row Address Setting */
u8x8_cad_SendArg(u8x8, 0x000);
u8x8_cad_SendArg(u8x8, 0x008 * ((u8x8_tile_t *)arg_ptr)->y_pos);
u8x8_cad_SendArg(u8x8, 0x000);
u8x8_cad_SendArg(u8x8, u8x8->display_info->pixel_height - 1); /* should this be u8x8->display_info->pixel_height - 1 */
u8x8_cad_SendCmd(u8x8, 0x02C); /* cmd write display data to ram */
c = ((u8x8_tile_t *) arg_ptr)->cnt; //
c *= 8;
ptr = ((u8x8_tile_t *) arg_ptr)->tile_ptr; //
// The ST7586S has an unusual 3 pixels per byte format so here we read in 3 bytes (24 pixels) and
// pack that into 8 bytes of 3 pixels each
while (c > 0) {
input = (((uint32_t)ptr[0] << 16) | ((uint32_t)ptr[1] << 8) | (uint32_t)ptr[2]);
for (i=0; i<8; i++)
{
byte = 0;
if (input & 0x800000) // if bit 23
byte = byte | 0xC0; //set pixel 1
if (input & 0x400000) // if bit 22
byte = byte | 0x18; //set pixel 2
if (input & 0x200000) // if bit 22
byte = byte | 0x3; //set pixel 3
output[i] = byte;
input <<= 3;
}
u8x8_cad_SendData(u8x8, 8, output);
ptr += 3;
c -= 3;
}
u8x8_cad_EndTransfer(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if (arg_int == 0)
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_off);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_sleep_on);
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x0C0);
u8x8_cad_SendArg(u8x8, arg_int);
u8x8_cad_SendArg(u8x8, 0);
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}
static const uint8_t u8x8_d_st7586s_s028hn118a_init_seq[] = {
U8X8_END_TRANSFER(),/* disable chip */
// U8G_ESC_RST(15), /* hardware reset */
U8X8_DLY(60), /* Delay 60 ms */
U8X8_START_TRANSFER(),/* enable chip */
U8X8_C(0x001), // Soft reset
U8X8_DLY(60), // Delay 120 ms
U8X8_C(0x011), // Sleep Out
U8X8_C(0x028), // Display OFF
U8X8_DLY(25), // Delay 50 ms
U8X8_CAA(0x0C0,0x0E5,0x00),// Vop = F0h in trace a bit too dark
U8X8_CA(0x0C3,0x004), // BIAS = 1/10 0x04 in trace
U8X8_CA(0x0C4,0x005), // Booster = x6 0x05 in trace
U8X8_CA(0x0D0,0x01D), // Enable Analog Circuit
U8X8_CA(0x0B3,0x000), // Set FOSC divider
U8X8_CA(0x0B5,0x08B), // N-Line = 0
U8X8_C(0x039), // 0x39 Monochrome mode. 0x38 - gray Mode
U8X8_C(0x03A), // Enable DDRAM Interface
U8X8_A(0x002), // monochrome and 4-level
U8X8_C(0x036), // Scan Direction Setting
U8X8_A(0x000), // COM0 -> COM159 SEG0 -> SEG384
U8X8_C(0x0B0), // Duty Setting (num rows - 1)
U8X8_A(0x087), // should be 0x87 but caused flicker 0x9F
U8X8_C(0x020), // Display inversion off
U8X8_C(0x02A), // Column Address Setting
U8X8_A(0x000), // COL0 -> COL127
U8X8_A(0x000), //
U8X8_A(0x000), //
U8X8_A(0x07f), // 128*3=384 pixels
U8X8_C(0x02B), // Row Address Setting
U8X8_A(0x000), // ROW0 -> ROW135
U8X8_A(0x000), //
U8X8_A(0x000), //
U8X8_A(0x087), // 136 pixels
U8X8_C(0x0F1), // Frame rate monochrome
U8X8_A(0x00C), // The factory firmware set this to 49.0 Hz 0x07
U8X8_A(0x00C), // This caused a shimmer under 50Hz LED lights
U8X8_A(0x00C), // 69.0 Hz (0x0C) fixes this and should avoid the
U8X8_A(0x00C), // issue in the US too
U8X8_C(0x029), // Display ON
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_st7586s_s028hn118a_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 5,
/* pre_chip_disable_wait_ns = */ 5,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 100, /* datasheet ST7586S */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* ST7586+Atmega128RFA1 works with 8MHz */
/* spi_mode = */ 3, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 20, /* datasheet suggests min 20 */
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 48,
/* tile_height = */ 17,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 384,
/* pixel_height = */ 136
};
/*******************************************************************************
* st7586s_s028hn118a driver. This is the display in the SMART Response XE. This requires 16 bit mode.
******************************************************************************/
uint8_t u8x8_d_st7586s_s028hn118a(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
if (u8x8_d_st7586s_common(u8x8, msg, arg_int, arg_ptr) != 0)
return 1;
switch (msg) {
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_s028hn118a_init_seq);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7586s_s028hn118a_display_info);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_s028hn118a_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_s028hn118a_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,256 @@
/*
u8x8_d_st7588.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ST7588
- has 4 different I2C addresses
- I2C protocol is identical to SSD13xx
*/
#include "u8x8.h"
/* function set, bit 2: power down, bit 3: MY, bit 4: MX, bit 5: must be 1 */
#define FS (0x020)
/* not a real power down for the ST7588... just a display off */
static const uint8_t u8x8_d_st7588_128x64_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C( FS | 0x00 ), /* select 00 commands */
//U8X8_C( 0x08 ), /* display off */
U8X8_C( 0x0c ), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7588_128x64_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C( FS | 0x00 ), /* select 00 commands */
U8X8_C( 0x08 ), /* display off */
//U8X8_C( 0x0c ), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static uint8_t u8x8_d_st7588_128x64_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
/* handled by the calling function
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7588_128x64_display_info);
break;
*/
/* handled by the calling function
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_128x64_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_128x64_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_128x64_powersave1_seq);
/* restore orientation */
if ( u8x8->x_offset == 0 )
u8x8_cad_SendCmd(u8x8, FS ); /* select 00 commands */
else
u8x8_cad_SendCmd(u8x8, FS ^ 0x018 ); /* select 00 commands */
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, FS );
u8x8_cad_SendArg(u8x8, 4 | (arg_int>>7) );
u8x8_cad_SendCmd(u8x8, FS | 1);
u8x8_cad_SendArg(u8x8, 0x080 | arg_int );
/* restore orientation */
if ( u8x8->x_offset == 0 )
u8x8_cad_SendCmd(u8x8, FS ); /* select 00 commands */
else
u8x8_cad_SendCmd(u8x8, FS ^ 0x018 ); /* select 00 commands */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
if ( u8x8->x_offset == 0 )
u8x8_cad_SendCmd(u8x8, FS ); /* select 00 commands */
else
u8x8_cad_SendCmd(u8x8, FS ^ 0x018 ); /* select 00 commands */
u8x8_cad_SendCmd(u8x8, 0x040 | (((u8x8_tile_t *)arg_ptr)->y_pos));
u8x8_cad_SendCmd(u8x8, 0x0e0 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0f0 | (x>>4) );
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
/*=============================================*/
static const u8x8_display_info_t u8x8_st7588_128x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 150,
/* pre_chip_disable_wait_ns = */ 30,
/* reset_pulse_width_ms = */ 5,
/* post_reset_wait_ms = */ 5, /**/
/* sda_setup_time_ns = */ 60, /* */
/* sck_pulse_width_ns = */ 60, /* */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4, /* 400KHz */
/* data_setup_time_ns = */ 80,
/* write_pulse_width_ns = */ 50,
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0, /* must be 0, because this is checked also for normal mode */
/* flipmode_x_offset = */ 4,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_st7588_128x64_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C( FS | 0x03 ), /* select 11 commands */
U8X8_C( 0x03 ), /* software reset */
U8X8_C( FS | 0x00 ), /* select 00 commands */
U8X8_C( 0x08 ), /* display off */
//U8X8_C( 0x0c ), /* display on */
U8X8_C( FS | 0x01 ), /* select 01 commands */
U8X8_C( 0x08 ), /* display confguration */
U8X8_C( 0x12 ), /* bias 1/9 */
U8X8_C( 0x8f ), /* Vop, lower 7 bits */
U8X8_C( FS | 0x00 ), /* select 00 commands */
U8X8_C( 0x05), /* Bit 0 contains high/low range for Vop */
U8X8_C( FS | 0x03 ), /* select 11 commands */
U8X8_C( 0x0b), /* Frame Rate: 73 Hz */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7588_jlx12864_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C( FS ), /* normal mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7588_jlx12864_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C( FS ^ 0x018 ), /* normal mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_st7588_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
if ( u8x8_d_st7588_128x64_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
return 1;
if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
{
u8x8_SetI2CAddress(u8x8, 0x07e); /* the JLX12864 has 0x07e as a default address for I2C */
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7588_128x64_display_info);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_INIT )
{
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_128x64_init_seq);
return 1;
}
else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
{
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_jlx12864_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_st7588_jlx12864_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
return 1;
}
return 0;
}

View File

@ -0,0 +1,236 @@
/*
u8x8_d_st7920.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The ST7920 controller does not support hardware graphics flip.
Contrast adjustment is done by an external resistor --> no support for contrast adjustment
*/
#include "u8x8.h"
static const uint8_t u8x8_d_st7920_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(10),
U8X8_C(0x038), /* 8 Bit interface (DL=1), basic instruction set (RE=0) */
U8X8_C(0x008), /* display on, cursor & blink off; 0x08: all off */
U8X8_C(0x006), /* Entry mode: Cursor move to right ,DDRAM address counter (AC) plus 1, no shift */
U8X8_C(0x002), /* disable scroll, enable CGRAM adress */
U8X8_C(0x001), /* clear RAM, needs 1.6 ms */
U8X8_DLY(4), /* delay 2ms */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7920_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x038), /* 8 Bit interface (DL=1), basic instruction set (RE=0) */
U8X8_C(0x00c), /* display on, cursor & blink off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_st7920_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x038), /* 8 Bit interface (DL=1), basic instruction set (RE=0) */
U8X8_C(0x008), /* display off */
U8X8_C(0x034), /* 8 Bit interface (DL=1), extended instruction set (RE=1) */
U8X8_C(0x001), /* Standby mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_st7920_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c, i;
uint8_t *ptr;
switch(msg)
{
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
/*
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
break;
*/
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_st7920_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_st7920_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_st7920_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y*=8;
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x /= 2; /* not sure whether this is a clever idea, problem is, the ST7920 can address only every second tile */
if ( y >= 32 ) /* this is the adjustment for 128x64 displays */
{
y-=32;
x+=8;
}
u8x8_cad_StartTransfer(u8x8);
/*
Tile structure is reused here for the ST7920, however u8x8 is not supported
tile_ptr points to data which has cnt*8 bytes (same as SSD1306 tiles)
Buffer is expected to have 8 lines of code fitting to the ST7920 internal memory
"cnt" includes the number of horizontal bytes. width is equal to cnt*8
Also important: Width must be a multiple of 16 (ST7920 requirement), so cnt must be even.
TODO: Consider arg_int, however arg_int is not used by u8g2
*/
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
/* The following byte is sent to allow the ST7920 to sync up with the data */
/* it solves some issues with garbage data */
u8x8_cad_SendCmd(u8x8, 0x03e ); /* enable extended mode */
u8x8_cad_SendCmd(u8x8, 0x03e ); /* enable extended mode, issue 487 */
for( i = 0; i < 8; i++ )
{
//u8x8_cad_SendCmd(u8x8, 0x03e ); /* enable extended mode */
u8x8_cad_SendCmd(u8x8, 0x080 | (y+i) ); /* y pos */
u8x8_cad_SendCmd(u8x8, 0x080 | x ); /* set x pos */
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes, send one line of data */
ptr += c;
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
}
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}
static const u8x8_display_info_t u8x8_st7920_192x32_display_info =
{
/* chip_enable_level = */ 1,
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 5,
/* pre_chip_disable_wait_ns = */ 5,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140, /* datasheet ST7920 */
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 3, /* old: sck_takeover_edge, new: active high (bit 1), rising edge (bit 0), 18 Aug 16: changed from 1 to 3 which works for 101 */
/* Arduino mode 3: aktive low clock, but use rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30,
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 24,
/* tile_hight = */ 4,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 192,
/* pixel_height = */ 32
};
static const u8x8_display_info_t u8x8_st7920_128x64_display_info =
{
/* chip_enable_level = */ 1,
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 5,
/* pre_chip_disable_wait_ns = */ 5,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140, /* datasheet ST7920 */
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* ST7920+Due work with 1MHz but not with 2MHz, ST7920+Uno works with 2MHz */
/* spi_mode = */ 3, /* active high, rising edge, 18 Aug 16: changed from 1 to 3 which works for 101 */
/* in theory mode 3 should be correct */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30,
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
uint8_t u8x8_d_st7920_192x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7920_192x32_display_info);
break;
default:
return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
uint8_t u8x8_d_st7920_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7920_128x64_display_info);
break;
default:
return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}

View File

@ -0,0 +1,101 @@
/*
u8x8_d_stdio.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
#include <stdio.h>
#define W 8
#define H 2
uint8_t bitmap[W*H*8];
void bitmap_place_tile(uint8_t x, uint8_t y, uint8_t *tile)
{
uint8_t i;
for(i = 0; i < 8; i++ )
bitmap[x*8+y*W*8+i] = tile[i];
}
void bitmap_show(void)
{
int x, y;
for( y = 0; y < H*8; y++ )
{
for( x = 0; x < W*8; x++ )
{
if ( (bitmap[x+(y/8)*W*8] & (1<<((y&7)))) != 0 )
{
printf("*");
}
else
{
printf(".");
}
}
printf("\n");
}
}
uint8_t u8x8_d_stdio(U8X8_UNUSED u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_INIT:
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
bitmap_show();
break;
case U8X8_MSG_DISPLAY_SET_CONTRAST:
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
bitmap_place_tile(((u8x8_tile_t *)arg_ptr)->x_pos, ((u8x8_tile_t *)arg_ptr)->y_pos, ((u8x8_tile_t *)arg_ptr)->tile_ptr);
break;
default:
break;
}
return 1;
}
void u8x8_SetupStdio(u8x8_t *u8x8)
{
u8x8_SetupDefaults(u8x8);
u8x8->display_cb = u8x8_d_stdio;
}

View File

@ -0,0 +1,564 @@
/*
u8x8_d_t6963.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The t6963 controller does not support hardware graphics flip.
Contrast adjustment is done by an external resistor --> no support for contrast adjustment
*/
#include "u8x8.h"
static const uint8_t u8x8_d_t6963_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x098), /* mode register: Display Mode, Graphics on, Text off, Cursor off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_t6963_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x090), /* All Off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_t6963_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t c, i;
uint16_t y;
uint8_t *ptr;
switch(msg)
{
/* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */
/*
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
break;
case U8X8_MSG_DISPLAY_INIT:
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_DRAW_TILE:
y = (((u8x8_tile_t *)arg_ptr)->y_pos);
y*=8;
y*= u8x8->display_info->tile_width;
/* x = ((u8x8_tile_t *)arg_ptr)->x_pos; x is ignored... no u8x8 support */
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
u8x8_cad_StartTransfer(u8x8);
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
/*
Tile structure is reused here for the t6963, however u8x8 is not supported
tile_ptr points to data which has cnt*8 bytes (same as SSD1306 tiles)
Buffer is expected to have 8 lines of code fitting to the t6963 internal memory
"cnt" includes the number of horizontal bytes. width is equal to cnt*8
TODO: Consider arg_int, however arg_int is not used by u8g2
*/
c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */
for( i = 0; i < 8; i++ )
{
u8x8_cad_SendArg(u8x8, y&255);
u8x8_cad_SendArg(u8x8, y>>8);
u8x8_cad_SendCmd(u8x8, 0x024 ); /* set adr */
u8x8_cad_SendCmd(u8x8, 0x0b0 ); /* auto write start */
//c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes, send one line of data */
u8x8_cad_SendCmd(u8x8, 0x0b2 ); /* auto write reset */
ptr += u8x8->display_info->tile_width;
y += u8x8->display_info->tile_width;
}
u8x8_cad_EndTransfer(u8x8);
//u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, 200, NULL); /* extra dely required */
break;
default:
return 0;
}
return 1;
}
/*=============================================*/
static const u8x8_display_info_t u8x8_t6963_240x128_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 110, /* T6963 Datasheet p30 */
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140,
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0,
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 80,
/* write_pulse_width_ns = */ 80,
/* tile_width = */ 30,
/* tile_hight = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 128
};
/* 240x128 */
static const uint8_t u8x8_d_t6963_240x128_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(100),
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
U8X8_AAC(240/8,0x00,0x041), /* low, high, set text columns */
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
U8X8_AAC(240/8,0x00,0x043), /* low, high, graphics columns */
U8X8_DLY(2), /* delay 2ms */
// mode set
// 0x080: Internal CG, OR Mode
// 0x081: Internal CG, EXOR Mode
// 0x083: Internal CG, AND Mode
// 0x088: External CG, OR Mode
// 0x089: External CG, EXOR Mode
// 0x08B: External CG, AND Mode
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
// display mode
// 0x090: Display off
// 0x094: Graphic off, text on, cursor off, blink off
// 0x096: Graphic off, text on, cursor on, blink off
// 0x097: Graphic off, text on, cursor on, blink on
// 0x098: Graphic on, text off, cursor off, blink off
// 0x09a: Graphic on, text off, cursor on, blink off
// ...
// 0x09c: Graphic on, text on, cursor off, blink off
// 0x09f: Graphic on, text on, cursor on, blink on
U8X8_C(0x090), /* All Off */
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
U8X8_DLY(100),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_DLY(100),
};
uint8_t u8x8_d_t6963_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_240x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_240x128_init_seq);
break;
default:
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
/*=============================================*/
static const u8x8_display_info_t u8x8_t6963_240x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 110, /* T6963 Datasheet p30 */
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140,
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0,
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 80,
/* write_pulse_width_ns = */ 80,
/* tile_width = */ 30,
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 64
};
/* 240x64 */
static const uint8_t u8x8_d_t6963_240x64_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(100),
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
U8X8_AAC(240/8,0x00,0x041), /* low, high, set text columns */
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
U8X8_AAC(240/8,0x00,0x043), /* low, high, graphics columns */
U8X8_DLY(2), /* delay 2ms */
// mode set
// 0x080: Internal CG, OR Mode
// 0x081: Internal CG, EXOR Mode
// 0x083: Internal CG, AND Mode
// 0x088: External CG, OR Mode
// 0x089: External CG, EXOR Mode
// 0x08B: External CG, AND Mode
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
// display mode
// 0x090: Display off
// 0x094: Graphic off, text on, cursor off, blink off
// 0x096: Graphic off, text on, cursor on, blink off
// 0x097: Graphic off, text on, cursor on, blink on
// 0x098: Graphic on, text off, cursor off, blink off
// 0x09a: Graphic on, text off, cursor on, blink off
// ...
// 0x09c: Graphic on, text on, cursor off, blink off
// 0x09f: Graphic on, text on, cursor on, blink on
U8X8_C(0x090), /* All Off */
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
U8X8_DLY(100),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_DLY(100),
};
uint8_t u8x8_d_t6963_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_240x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_240x64_init_seq);
break;
default:
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
/*=============================================*/
static const u8x8_display_info_t u8x8_t6963_256x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 110, /* T6963 Datasheet p30 */
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140,
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0,
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 80,
/* write_pulse_width_ns = */ 80,
/* tile_width = */ 32,
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 256,
/* pixel_height = */ 64
};
/* 256x64 */
static const uint8_t u8x8_d_t6963_256x64_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(100),
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
U8X8_AAC(256/8,0x00,0x041), /* low, high, set text columns */
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
U8X8_AAC(256/8,0x00,0x043), /* low, high, graphics columns */
U8X8_DLY(2), /* delay 2ms */
// mode set
// 0x080: Internal CG, OR Mode
// 0x081: Internal CG, EXOR Mode
// 0x083: Internal CG, AND Mode
// 0x088: External CG, OR Mode
// 0x089: External CG, EXOR Mode
// 0x08B: External CG, AND Mode
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
// display mode
// 0x090: Display off
// 0x094: Graphic off, text on, cursor off, blink off
// 0x096: Graphic off, text on, cursor on, blink off
// 0x097: Graphic off, text on, cursor on, blink on
// 0x098: Graphic on, text off, cursor off, blink off
// 0x09a: Graphic on, text off, cursor on, blink off
// ...
// 0x09c: Graphic on, text on, cursor off, blink off
// 0x09f: Graphic on, text on, cursor on, blink on
U8X8_C(0x090), /* All Off */
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
U8X8_DLY(100),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_DLY(100),
};
uint8_t u8x8_d_t6963_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_256x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_256x64_init_seq);
break;
default:
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
/*=============================================*/
static const u8x8_display_info_t u8x8_t6963_128x64_display_info =
{
/* chip_enable_level = */ 1,
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 10, /* T6963 Datasheet p30 */
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140,
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0,
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 80,
/* write_pulse_width_ns = */ 80,
/* tile_width = */ 16,
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
/* 128x64 */
static const uint8_t u8x8_d_t6963_128x64_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(100),
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
U8X8_AAC(128/8,0x00,0x041), /* low, high, set text columns */
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
U8X8_AAC(128/8,0x00,0x043), /* low, high, graphics columns */
U8X8_DLY(2), /* delay 2ms */
// mode set
// 0x080: Internal CG, OR Mode
// 0x081: Internal CG, EXOR Mode
// 0x083: Internal CG, AND Mode
// 0x088: External CG, OR Mode
// 0x089: External CG, EXOR Mode
// 0x08B: External CG, AND Mode
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
// display mode
// 0x090: Display off
// 0x094: Graphic off, text on, cursor off, blink off
// 0x096: Graphic off, text on, cursor on, blink off
// 0x097: Graphic off, text on, cursor on, blink on
// 0x098: Graphic on, text off, cursor off, blink off
// 0x09a: Graphic on, text off, cursor on, blink off
// ...
// 0x09c: Graphic on, text on, cursor off, blink off
// 0x09f: Graphic on, text on, cursor on, blink on
U8X8_C(0x090), /* All Off */
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
U8X8_DLY(100),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_DLY(100),
};
uint8_t u8x8_d_t6963_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_128x64_init_seq);
break;
default:
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
/*=============================================*/
static const u8x8_display_info_t u8x8_t6963_160x80_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 10, /* T6963 Datasheet p30 */
/* pre_chip_disable_wait_ns = */ 100, /* T6963 Datasheet p30 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 20,
/* sck_pulse_width_ns = */ 140,
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0,
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 80,
/* write_pulse_width_ns = */ 80,
/* tile_width = */ 20,
/* tile_hight = */ 10,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 160,
/* pixel_height = */ 80
};
/* 128x64 */
static const uint8_t u8x8_d_t6963_160x80_init_seq[] = {
U8X8_DLY(100),
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(100),
U8X8_AAC(0x00,0x00,0x021), /* low, high, set cursor pos */
U8X8_AAC(0x00,0x00,0x022), /* low, high, set offset */
U8X8_AAC(0x00,0x00,0x040), /* low, high, set text home */
U8X8_AAC(160/8,0x00,0x041), /* low, high, set text columns */
U8X8_AAC(0x00,0x00,0x042), /* low, high, graphics home */
U8X8_AAC(160/8,0x00,0x043), /* low, high, graphics columns */
U8X8_DLY(2), /* delay 2ms */
// mode set
// 0x080: Internal CG, OR Mode
// 0x081: Internal CG, EXOR Mode
// 0x083: Internal CG, AND Mode
// 0x088: External CG, OR Mode
// 0x089: External CG, EXOR Mode
// 0x08B: External CG, AND Mode
U8X8_C(0x080), /* mode register: OR Mode, Internal Character Mode */
// display mode
// 0x090: Display off
// 0x094: Graphic off, text on, cursor off, blink off
// 0x096: Graphic off, text on, cursor on, blink off
// 0x097: Graphic off, text on, cursor on, blink on
// 0x098: Graphic on, text off, cursor off, blink off
// 0x09a: Graphic on, text off, cursor on, blink off
// ...
// 0x09c: Graphic on, text on, cursor off, blink off
// 0x09f: Graphic on, text on, cursor on, blink on
U8X8_C(0x090), /* All Off */
U8X8_AAC(0x00,0x00,0x024), /* low, high, set adr pointer */
U8X8_DLY(100),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_DLY(100),
};
uint8_t u8x8_d_t6963_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_160x80_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_160x80_init_seq);
break;
default:
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}
/* alternative version for the 128x64 t6963 display: use the 160x80 init sequence */
uint8_t u8x8_d_t6963_128x64_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_t6963_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_160x80_init_seq);
break;
default:
return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
}
return 1;
}

View File

@ -0,0 +1,188 @@
/*
u8x8_d_uc1601.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This is for the uc1601s controller
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1601_128x32_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1601_128x32_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1601_128x32_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c4), /* bit 1: MX, bit 2: MY */
U8X8_C(0x060), /* set display start line to 32 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1601_128x32_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c2), /* bit 1: MX, bit 2: MY */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_uc1601_128x32_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 1, /* uc1601 datasheet, page 46 */
/* pre_chip_disable_wait_ns = */ 5, /* uc1601 datasheet, page 46 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 12, /* uc1601 datasheet, page 44 */
/* sck_pulse_width_ns = */ 15, /* uc1601 datasheet, page 44 */
/* sck_clock_hz = */ 2000000UL, /* */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 1,
/* data_setup_time_ns = */ 60, /* uc1601 datasheet, page 43 */
/* write_pulse_width_ns = */ 80, /* uc1601 datasheet, page 43 */
/* tile_width = */ 16,
/* tile_hight = */ 4,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 4,
/* pixel_width = */ 128,
/* pixel_height = */ 32
};
static const uint8_t u8x8_d_uc1601_128x32_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_C(0x0eb), /* LCD Bias: 0xe8: 6, 0xe9: 7, 0xea: 8, 0xeb: 9 */
//U8X8_C(0x023), /* 0x020...0x023 only for UC1601, not for UC1601s */
//U8X8_C(0x02e), /* LCD Load + Internal Charge Pump (default: 0x2e) */
U8X8_C(0x024), /* Temperature Compenstation, default: 0x24 */
U8X8_C(0x089), /* RAM address ctrl, default: 0x89 */
U8X8_C(0x0c4), /* RAM mapping ctrl */
U8X8_C(0x0a0), /* Frame Rate, 0x0a0 or 0x0a1 */
U8X8_CA(0x081, 0x0df), /* set contrast */
U8X8_C(0x02e), /* LCD Load + Internal Charge Pump (default: 0x2e) */
U8X8_C(0x060), /* set display start line to 32 */
U8X8_C(0x0a6), /* normal display */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1601_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1601_128x32_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1601_128x32_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1601 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,240 @@
/*
u8x8_d_uc1604.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1604_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_DLY(20),
U8X8_C(0x0af), /* display on */
U8X8_DLY(20), /* during setup, it seems that the startup is more reliable when sending this cmd twice */
U8X8_C(0x0af), /* display on */
U8X8_DLY(50), /* startup takes some time */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1604_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off, enter sleep mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1604_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c4), /* LCD Mapping */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1604_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c2), /* LCD Mapping */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1604_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
y += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x0b0 | (y&15));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
/* handled in the calling procedure
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1604_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1604 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}
/*================================================*/
/* JLX19264 */
/*
timings from uc1608
UC1604 has two chip select inputs (CS0 and CS1).
CS0 is low active, CS1 is high active. It will depend on the display
module whether the display has a is low or high active chip select.
*/
static const u8x8_display_info_t u8x8_uc1604_192x64_display_info =
{
/* chip_enable_level = */ 0, /* JLX19264G uses CS0, which is low active CS*/
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 20,
/* pre_chip_disable_wait_ns = */ 20,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 10,
/* sda_setup_time_ns = */ 30,
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30,
/* write_pulse_width_ns = */ 35,
/* tile_width = */ 24, /* width of 24*8=192 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0, /* reused as y page offset */
/* flipmode_x_offset = */ 0, /* reused as y page offset */
/* pixel_width = */ 192,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_uc1604_jlx19264_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_DLY(200),
U8X8_DLY(200),
U8X8_C(0x02f), /* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
U8X8_DLY(200),
U8X8_DLY(200),
U8X8_CA(0x081, 0x052), /* set contrast, JLX19264G suggestion: 0x045 */
U8X8_C(0x0eb), /* LCD bias Bits 0/1: 00=6 01=7, 10=8, 11=9 */
//U8X8_C(0x023), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
//U8X8_C(0x027), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
U8X8_C(0x0c4), /* Map control, Bit 2: MY=1, Bit 1: MX=0 */
U8X8_C(0x0a0), /* 0xa0: 76Hz FPS, controller default: 0x0a1: 95Hz FPS */
U8X8_C(0x040), /* set scroll line to 0 */
U8X8_C(0x089), /* RAM access control (controller default: 0x089)*/
U8X8_C(0x000), /* column low nibble */
U8X8_C(0x010), /* column high nibble */
U8X8_C(0x0b0), /* page adr */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1604_jlx19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_uc1604_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1604_192x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_jlx19264_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}

View File

@ -0,0 +1,393 @@
/*
u8x8_d_uc1608.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1608_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1608_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off, enter sleep mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1608_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c8), /* LCD Mapping */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1608_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c4), /* LCD Mapping */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1608_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
y += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x0b0 | (y&15));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
/* handled in the calling procedure
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1608_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1608 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}
/*================================================*/
/* ERC24064-1 */
/*
The UC1608 has only one high active chip select input.
UC1604, UC1610 and UC1611 have two chip select inputs.
*/
static const u8x8_display_info_t u8x8_uc1608_240x64_display_info =
{
/* chip_enable_level = */ 1, /* uc1608 has high active CS */
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 10, /* uc1608 datasheet, page 39, actually 0 */
/* pre_chip_disable_wait_ns = */ 20, /* uc1608 datasheet, page 39 */
/* reset_pulse_width_ms = */ 1, /* uc1608 datasheet, page 42 */
/* post_reset_wait_ms = */ 10,
/* sda_setup_time_ns = */ 30, /* uc1608 datasheet, page 41 */
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30, /* uc1608 datasheet, page 39 */
/* write_pulse_width_ns = */ 35, /* uc1608 datasheet, page 39 */
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0, /* reused as y page offset */
/* flipmode_x_offset = */ 4, /* reused as y page offset */
/* pixel_width = */ 240,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_uc1608_erc24064_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_DLY(200),
U8X8_C(0x023), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
//U8X8_C(0x027), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
U8X8_C(0x0c8), /* Map control, Bit 3: MY=1, Bit 2: MX=0, Bit 0: MSF =0 */
U8X8_C(0x0e8), /* LCD bias Bits 0/1: 00=10.7 01=10.3, 10=12.0, 11=12.7 */
U8X8_C(0x02f), /* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
U8X8_DLY(50),
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x090), /* no fixed lines */
U8X8_C(0x089), /* RAM access control */
U8X8_CA(0x081, 0x014), /* set contrast, ERC24064-1 default: 0x040 */
U8X8_C(0x000), /* column low nibble */
U8X8_C(0x010), /* column high nibble */
U8X8_C(0x0b0), /* page adr */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1608_erc24064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_uc1608_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1608_240x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_erc24064_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/
/* experimental implementation for the uc1608 240x128, not referenced in codebuild */
static const u8x8_display_info_t u8x8_uc1608_240x128_display_info =
{
/* chip_enable_level = */ 1, /* uc1608 has high active CS */
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 10, /* uc1608 datasheet, page 39, actually 0 */
/* pre_chip_disable_wait_ns = */ 20, /* uc1608 datasheet, page 39 */
/* reset_pulse_width_ms = */ 1, /* uc1608 datasheet, page 42 */
/* post_reset_wait_ms = */ 10,
/* sda_setup_time_ns = */ 30, /* uc1608 datasheet, page 41 */
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30, /* uc1608 datasheet, page 39 */
/* write_pulse_width_ns = */ 35, /* uc1608 datasheet, page 39 */
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 16,
/* default_x_offset = */ 0, /* reused as y page offset */
/* flipmode_x_offset = */ 0, /* reused as y page offset */
/* pixel_width = */ 240,
/* pixel_height = */ 128
};
static const uint8_t u8x8_d_uc1608_240x128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_DLY(200),
//U8X8_C(0x023), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
U8X8_C(0x026), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
U8X8_C(0x0c8), /* Map control, Bit 3: MY=1, Bit 2: MX=0, Bit 0: MSF =0 */
U8X8_C(0x0ea), /* LCD bias Bits 0/1: 00=10.7 01=10.3, 10=12.0, 11=12.7 */
/* maybe 0x0eb??? */
U8X8_C(0x02f), /* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
U8X8_DLY(50),
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x090), /* no fixed lines */
U8X8_C(0x089), /* RAM access control */
U8X8_CA(0x081, 0x072), /* set contrast */
U8X8_C(0x000), /* column low nibble */
U8X8_C(0x010), /* column high nibble */
U8X8_C(0x0b0), /* page adr */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1608_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_uc1608_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1608_240x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_240x128_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/
/* experimental implementation for the uc1608 erc240x120 */
static const u8x8_display_info_t u8x8_uc1608_erc240120_display_info =
{
/* chip_enable_level = */ 1, /* uc1608 has high active CS */
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 10, /* uc1608 datasheet, page 39, actually 0 */
/* pre_chip_disable_wait_ns = */ 20, /* uc1608 datasheet, page 39 */
/* reset_pulse_width_ms = */ 1, /* uc1608 datasheet, page 42 */
/* post_reset_wait_ms = */ 10,
/* sda_setup_time_ns = */ 30, /* uc1608 datasheet, page 41 */
/* sck_pulse_width_ns = */ 65, /* half of cycle time */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30, /* uc1608 datasheet, page 39 */
/* write_pulse_width_ns = */ 35, /* uc1608 datasheet, page 39 */
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 15,
/* default_x_offset = */ 1, /* reused as y page offset */
/* flipmode_x_offset = */ 0, /* reused as y page offset */
/* pixel_width = */ 240,
/* pixel_height = */ 120
};
/* http://www.buydisplay.com/download/democode/ERC240120-1_DemoCode.txt */
static const uint8_t u8x8_d_uc1608_erc240120_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_DLY(200),
//U8X8_C(0x023), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
U8X8_C(0x026), /* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
U8X8_C(0x0c8), /* Map control, Bit 3: MY=1, Bit 2: MX=0, Bit 0: MSF =0 */
U8X8_C(0x0ea), /* LCD bias Bits 0/1: 00=10.7 01=10.3, 10=12.0, 11=12.7 */
/* according to DemoCode.txt */
U8X8_C(0x02f), /* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
U8X8_DLY(50),
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x090), /* no fixed lines */
U8X8_C(0x089), /* RAM access control */
//U8X8_CA(0x081, 46), /* set contrast, 46 according to DemoCode.txt */
U8X8_CA(0x081, 80), /* */
U8X8_C(0x000), /* column low nibble */
U8X8_C(0x010), /* column high nibble */
U8X8_C(0x0b0), /* page adr */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1608_erc240120(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_uc1608_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1608_erc240120_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1608_erc240120_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/

View File

@ -0,0 +1,304 @@
/*
u8x8_d_uc1610.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cad001
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1610_dogxl160_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0f1, 0x067), /* set COM end (display height-1) */
U8X8_C(0x0c0), /* SEG & COM normal */
U8X8_C(0x040), /* set scroll line lsb to zero */
U8X8_C(0x050), /* set scroll line msb to zero */
U8X8_C(0x02b), /* set panelloading */
U8X8_C(0x0eb), /* set bias 1/2 */
U8X8_CA(0x081, 0x05f), /* set contrast */
/*
AC0: 0: stop at boundary, 1: increment by one
AC1: 0: first column then page, 1: first page, then column increment
AC2: 0: increment page adr, 1: decrement page adr.
*/
U8X8_C(0x08b), /* set auto increment, low bits are AC2 AC1 AC0 */
/*
LC0: 0
MX: Mirror X
MY: Mirror Y
*/
U8X8_C(0x0c0), /* low bits are MY, MX, LC0 */
U8X8_C(0x0f8), // window mode off
U8X8_C(0x010), // col high
U8X8_C(0x000), // col low
U8X8_C(0x0b0), // page
U8X8_C(0x0a6), /* set normal pixel mode (not inverse) */
U8X8_C(0x0a4), /* set normal pixel mode (not all on) */
/* test code
U8X8_C(0x0af), // display on
U8X8_C(0x0f8), // window mode off
U8X8_CA(0x0f4, 0), // set window
U8X8_CA(0x0f5, 0),
U8X8_CA(0x0f6, 4),
U8X8_CA(0x0f7, 1),
U8X8_C(0x0f9), // window mode on
U8X8_D1(0x03),
U8X8_D1(0x0c0),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
*/
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1610_dogxl160_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on, UC1610 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1610_dogxl160_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off, UC1610 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1610_dogxl160_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
/*
LC0: 0
MX: Mirror X
MY: Mirror Y
*/
U8X8_C(0x0c0), /* low bits are MY, MX, LC0 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1610_dogxl160_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
/*
LC0: 0
MX: Mirror X
MY: Mirror Y
*/
U8X8_C(0x0c6), /* low bits are MY, MX, LC0 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/*
UC1610 has two chip select inputs (CS0 and CS1).
CS0 is low active, CS1 is high active. It will depend on the display
module whether the display has a is low or high active chip select.
*/
static const u8x8_display_info_t u8x8_uc1610_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 15,
/* pre_chip_disable_wait_ns = */ 15,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 30,
/* sck_pulse_width_ns = */ 63, /* half of cycle time (125ns cycle time according to datasheet) --> 8MHz clock */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30,
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 20,
/* tile_hight = */ 13, /* height of 13*8=104 pixel */
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 160,
/* pixel_height = */ 104
};
/*
RAM Organization:
D0 Pix0
D1
D2 Pix1
D3
D4 Pix2
D5
D6 Pix3
D7
D0 Pix4
D1
D2 Pix5
D3
D4 Pix6
D5
D6 Pix7
D7
*/
static uint8_t *u8x8_convert_tile_for_uc1610(uint8_t *t)
{
uint8_t i;
uint16_t r;
static uint8_t buf[16];
uint8_t *pbuf = buf;
for( i = 0; i < 8; i++ )
{
r = u8x8_upscale_byte(*t++);
*pbuf++ = r & 255;
r >>= 8;
*pbuf++ = r;
}
return buf;
}
uint8_t u8x8_d_uc1610_ea_dogxl160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c, page;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1610_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1610_dogxl160_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1610 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
page = (((u8x8_tile_t *)arg_ptr)->y_pos);
page *= 2;
u8x8_cad_SendCmd(u8x8, 0x0f8 ); /* window disable */
//u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
//u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
//u8x8_cad_SendCmd(u8x8, 0x0b0 | page);
u8x8_cad_SendCmd(u8x8, 0x0f4 ); /* window start column */
u8x8_cad_SendArg(u8x8, x);
u8x8_cad_SendCmd(u8x8, 0x0f5 ); /* window start page */
u8x8_cad_SendArg(u8x8, page);
u8x8_cad_SendCmd(u8x8, 0x0f6 ); /* window end column */
u8x8_cad_SendArg(u8x8, 159); /* end of display */
u8x8_cad_SendCmd(u8x8, 0x0f7 ); /* window end page */
u8x8_cad_SendArg(u8x8, page+1);
u8x8_cad_SendCmd(u8x8, 0x0f9 ); /* window enable */
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, 16, u8x8_convert_tile_for_uc1610(ptr));
ptr += 8;
x += 8;
c--;
} while( c > 0 );
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,502 @@
/*
u8x8_d_uc1611.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6 Nov 2016: Not yet finished
There are two controller:
UC1611s 160x256
UC1611 160x240
Differences:
UC1611 0xa8 cmd: enables 80 display rows
UC1611s 0xa8 cmd: controlls graylevels
UC1611 0xc0 cmd: single byte command for LCD mapping control
UC1611s 0xc0 cmd: double byte command for LCD mapping control
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1611s_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a9), /* display on, UC1611s */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1611s_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a8), /* display off, enter sleep mode, UC1611s */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1611s_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0c0, 0x004), /* LCD Mapping */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1611s_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0c0, 0x002), /* LCD Mapping */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1611_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
u8x8_cad_SendCmd(u8x8, 0x060 | (y&15));
u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
/* handled in the calling procedure
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
break;
*/
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1611 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}
/*================================================*/
/* EA DOGM240 */
/*
UC1611 has two chip select inputs (CS0 and CS1).
CS0 is low active, CS1 is high active. It will depend on the display
module whether the display has a is low or high active chip select.
*/
static const u8x8_display_info_t u8x8_uc1611_240x64_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
/* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */
/* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */
/* sck_pulse_width_ns = */ 60, /* half of cycle time */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */
/* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 64
};
static const uint8_t u8x8_d_uc1611_ea_dogm240_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x02f), /* internal pump control */
U8X8_CA(0x0f1, 63), /* set COM end */
U8X8_CA(0x0f2, 0x000), /* display line start */
U8X8_CA(0x0f3, 63), /* display line end */
U8X8_C(0x0a3), /* line rate */
U8X8_CA(0x081, 0x0a4), /* set contrast, EA default: 0x0b7 */
//U8X8_C(0x0a9), /* display enable */
U8X8_C(0x0d1), /* display pattern */
U8X8_C(0x089), /* auto increment */
U8X8_CA(0x0c0, 0x004), /* LCD Mapping */
U8X8_C(0x000), /* column low nibble */
U8X8_C(0x010), /* column high nibble */
U8X8_C(0x060), /* page adr low */
U8X8_C(0x070), /* page adr high */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* UC1611s 240x64 display */
uint8_t u8x8_d_uc1611_ea_dogm240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_uc1611_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_240x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ea_dogm240_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/
/* EA DOGXL240 */
static const uint8_t u8x8_d_uc1611_ea_dogxl240_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x02f), /* internal pump control */
U8X8_CA(0x0f1, 0x07f), /* set COM end */
U8X8_CA(0x0f2, 0x000), /* display line start */
U8X8_CA(0x0f3, 127), /* display line end */
U8X8_C(0x0a3), /* line rate */
U8X8_CA(0x081, 0x08f), /* set contrast */
//U8X8_C(0x0a9), /* display enable */
U8X8_C(0x0d1), /* display pattern */
U8X8_C(0x089), /* auto increment */
U8X8_CA(0x0c0, 0x004), /* LCD Mapping */
U8X8_C(0x000), /* column low nibble */
U8X8_C(0x010), /* column high nibble */
U8X8_C(0x060), /* page adr low */
U8X8_C(0x070), /* page adr high */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_uc1611_240x128_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
/* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */
/* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */
/* sck_pulse_width_ns = */ 60, /* half of cycle time */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */
/* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 128
};
/* UC1611s 240x128 display */
uint8_t u8x8_d_uc1611_ea_dogxl240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_uc1611_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_240x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ea_dogxl240_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611s_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/
/* EMERGING DISPLAY, EW50850FLWP 240x160 */
/* active high CS (CS1), UC1611 display */
static const uint8_t u8x8_d_uc1611_ew50850_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x02f), /* internal pump control */
U8X8_CA(0x0f1, 159), /* set COM end */
U8X8_CA(0x0f2, 0), /* display line start */
U8X8_CA(0x0f3, 159), /* display line end */
U8X8_C(0x0a3), /* line rate */
U8X8_CA(0x081, 75), /* set contrast */
//U8X8_C(0x0a9), /* display enable */
U8X8_C(0x0d2), /* gray level mode: 16 gray shades */
U8X8_C(0x089), /* auto increment */
U8X8_C(0x0c0), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */
U8X8_C(0x000), /* column low nibble */
U8X8_C(0x010), /* column high nibble */
U8X8_C(0x060), /* page adr low */
U8X8_C(0x070), /* page adr high */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_uc1611_ew50850_display_info =
{
/* chip_enable_level = */ 1, /* active high */
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
/* pre_chip_disable_wait_ns = */ 10, /* uc1611 datasheet, page 60, actually 0 */
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 10, /* uc1611 datasheet, page 67 */
/* sda_setup_time_ns = */ 10, /* uc1611 datasheet, page 64, actually 0 */
/* sck_pulse_width_ns = */ 60, /* half of cycle time */
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30, /* uc1611 datasheet, page 60 */
/* write_pulse_width_ns = */ 80, /* uc1611 datasheet, page 60 */
/* tile_width = */ 30, /* width of 30*8=240 pixel */
/* tile_hight = */ 20, /* height: 160 pixel */
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 240,
/* pixel_height = */ 160
};
static const uint8_t u8x8_d_uc1611_alt_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c0), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1611_alt_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c6), /* LCD Mapping Bit 0: MSF, Bit 1: MX, Bit 2: MY */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1611_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0af), /* display on, UC1611 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1611_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a8), /* display off, enter sleep mode, UC1611 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
/* EW50850, 240x160 */
uint8_t u8x8_d_uc1611_ew50850(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c, i, v, m0, m1, ai;
uint8_t *ptr;
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
y*=4;
m0 = 1;
m1 = 2;
for( i = 0; i < 4; i++ )
{
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x060 | (y&15));
u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4));
ai = arg_int;
do
{
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
while( c > 0 )
{
v = 0;
if ( *ptr & m0 )
v|= 0x0f;
if ( *ptr & m1 )
v|= 0xf0;
u8x8_cad_SendData(u8x8, 1, &v); /* note: SendData can not handle more than 255 bytes */
c--;
ptr++;
}
ai--;
} while( ai > 0 );
m0 <<= 2;
m1 <<= 2;
y++;
}
u8x8_cad_EndTransfer(u8x8);
break;
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1611_ew50850_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_ew50850_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_alt_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1611_alt_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1611 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0; /* msg unknown */
}
return 1;
}

View File

@ -0,0 +1,241 @@
/*
u8x8_d_uc1617.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2017, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1617_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ad), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1617_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ac), /* display off, enter sleep mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1617_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c4), /* LCD Mapping */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1617_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c2), /* LCD Mapping */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1617_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
u8x8_cad_SendCmd(u8x8, 0x060 | (y&15));
u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1617 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}
/*================================================*/
/* JLX128128 */
static const uint8_t u8x8_d_uc1617_jlx128128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* reset */
U8X8_DLY(10),
//U8X8_D1(0x0ff),
U8X8_C(0x027), /* temperature compensation */
U8X8_C(0x02b), /* panel loading: 13-18nF */
U8X8_C(0x02f), /* internal pump control */
U8X8_C(0x0eb), /* bias=1/11 */
U8X8_CA(0x081, 0x066), /* set contrast */
//U8X8_C(0x0a9), /* used in display datasheet, but cmd not described in controller datasheet */
U8X8_CA(0x0f1, 0x07f), /* set COM end */
U8X8_CA(0x0f2, 0x000), /* display line start */
U8X8_CA(0x0f3, 127), /* display line end */
U8X8_C(0x0a3), /* line rate */
U8X8_C(0x0d3), /* */
U8X8_C(0x0d7), /* */
U8X8_C(0x0ad), /* display enable BW Mode*/
//U8X8_C(0x0af), /* display enable GS Mode*/
//U8X8_C(0x0a5), /* all pixel on */
//U8X8_C(0x0d1), /* display pattern */
U8X8_C(0x089), /* auto increment */
U8X8_C(0x0c4), /* LCD Mapping */
U8X8_C(0x000), /* column */
U8X8_C(0x060), /* page adr low */
U8X8_C(0x070), /* page adr high */
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_D1(0x0ff),
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_uc1617_128x128_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 10, /* uc1617 datasheet, page 54, actually 5 */
/* pre_chip_disable_wait_ns = */ 10, /* uc1617 datasheet, page 54, actually 5 */
/* reset_pulse_width_ms = */ 10,
/* post_reset_wait_ms = */ 20, /* uc1617 datasheet, page 56 */
/* sda_setup_time_ns = */ 24, /* uc1617 datasheet, page 54 */
/* sck_pulse_width_ns = */ 45, /* half of cycle time uc1617 datasheet, page 54*/
/* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30, /* uc1617 datasheet, page 52 */
/* write_pulse_width_ns = */ 65, /* uc1617 datasheet, page 52 */
/* tile_width = */ 16, /* width of 16*8=128 pixel */
/* tile_hight = */ 16,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 128,
/* pixel_height = */ 128
};
uint8_t u8x8_d_uc1617_jlx128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_uc1617_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1617_128x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1617_jlx128128_init_seq);
for(;;)
;
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}

View File

@ -0,0 +1,223 @@
/*
u8x8_d_uc1638.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1638_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0c9, 0x0ad), /* display on */ /* UC1638 B/W mode */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1638_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0c9, 0x0ac), /* display off */ /* UC1638 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1638_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c4), /* LCD Mapping */ /* UC1638*/
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1638_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0c2), /* LCD Mapping */ /* UC1638*/
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1638_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, y, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
u8x8_cad_SendCmd(u8x8, 0x004); /* UC1638 */
u8x8_cad_SendArg(u8x8, x);
y = ((u8x8_tile_t *)arg_ptr)->y_pos;
y += u8x8->x_offset;
y *= 2; /* for B/W mode, use only every second page */
u8x8_cad_SendCmd(u8x8, 0x060 | (y&15)); /* UC1638 */
u8x8_cad_SendCmd(u8x8, 0x070 | (y>>4)); /* UC1638 */
u8x8_cad_SendCmd(u8x8, 0x001); /* UC1638 */
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
/* handled in the calling procedure
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1638_128x64_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
break;
*/
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int ); /* uc1638 has range from 0 to 255 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
default:
return 0;
}
return 1;
}
/*================================================*/
/* uc1638 160x128 */
/* values taken from uc1608 */
static const u8x8_display_info_t u8x8_uc1638_160x128_display_info =
{
/* chip_enable_level = */ 1, /* uc1638 has high active CS */
/* chip_disable_level = */ 0,
/* post_chip_enable_wait_ns = */ 10, /* */
/* pre_chip_disable_wait_ns = */ 20, /* */
/* reset_pulse_width_ms = */ 5, /* */
/* post_reset_wait_ms = */ 150,
/* sda_setup_time_ns = */ 30, /* */
/* sck_pulse_width_ns = */ 65, /* */
/* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 3, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30, /* */
/* write_pulse_width_ns = */ 35, /* */
/* tile_width = */ 20, /* width of 20*8=160 pixel */
/* tile_hight = */ 16,
/* default_x_offset = */ 0, /* */
/* flipmode_x_offset = */ 0, /* */
/* pixel_width = */ 160,
/* pixel_height = */ 128
};
static const uint8_t u8x8_d_uc1638_160x128_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_CA(0x0e1, 0x0e2), /* software reset */ /* UC1638*/
U8X8_DLY(5), /* 5 ms */
U8X8_C(0x024), /* set temp comp*/
U8X8_C(0x0c0), /* mirror y and mirror x */ /* WAS: c2 */
U8X8_C(0x0a2), /* line rate */
U8X8_C(0x0d6), /* gray scale 2 */
U8X8_C(0x0eb), /* set bias*/
U8X8_C(0x095), /* set 1 bit per pixel, pattern 0*/
U8X8_C(0x089), /* set auto increment, low bits are AC2 AC1 AC0 */ /* WAS 89 */
U8X8_CA(0x081, 0x0a0), /* set contrast */ /* UC1638*/
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
uint8_t u8x8_d_uc1638_160x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
/* call common procedure first and handle messages there */
if ( u8x8_d_uc1638_common(u8x8, msg, arg_int, arg_ptr) == 0 )
{
/* msg not handled, then try here */
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1638_160x128_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_160x128_init_seq);
break;
default:
return 0; /* msg unknown */
}
}
return 1;
}
/*================================================*/

View File

@ -0,0 +1,203 @@
/*
u8x8_d_uc1701_dogs102.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1701_dogs102_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x0a1), /* ADC set to reverse */
U8X8_C(0x0c0), /* common output mode */
// Flipmode
//U8X8_C(0x0a0), /* ADC set to reverse */
//U8X8_C(0x0c8), /* common output mode */
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
U8X8_C(0x0a2), /* LCD bias 1/9 */
U8X8_C(0x02f), /* all power control circuits on */
U8X8_C(0x027), /* regulator, booster and follower */
U8X8_CA(0x081, 0x00e), /* set contrast, contrast value, EA default: 0x010, previous value for S102: 0x0e */
U8X8_C(0x0fa), /* Set Temp compensation */
U8X8_C(0x090), /* 0.11 deg/c WP Off WC Off*/
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1701_dogs102_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a4), /* all pixel off, issue 142 */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1701_dogs102_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1701_dogs102_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1701_dogs102_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_uc1701_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 5,
/* pre_chip_disable_wait_ns = */ 5,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 12,
/* sck_pulse_width_ns = */ 75, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30,
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 13, /* width of 13*8=104 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 30,
/* pixel_width = */ 102,
/* pixel_height = */ 64
};
uint8_t u8x8_d_uc1701_ea_dogs102(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1701_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_dogs102_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* uc1701 has range from 0 to 63 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
/*
The following if condition checks the hardware limits of the uc1701
controller: It is not allowed to write beyond the display limits.
This is in fact an issue within flip mode.
*/
if ( c + x > 132u )
{
c = 132u;
c -= x;
}
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,205 @@
/*
u8x8_d_uc1701_mini12864.c (dealextreme, displays from ebay MP3 players)
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const uint8_t u8x8_d_uc1701_mini12864_init_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0e2), /* soft reset */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x040), /* set display start line to 0 */
U8X8_C(0x0a0), /* ADC set to reverse */
U8X8_C(0x0c8), /* common output mode */
U8X8_C(0x0a6), /* display normal, bit val 0: LCD pixel off. */
U8X8_C(0x0a2), /* LCD bias 1/9 */
U8X8_C(0x02f), /* all power control circuits on */
U8X8_C(0x0f8), /* set booster ratio to */
U8X8_C(0x000), /* 4x */
U8X8_C(0x023), /* set V0 voltage resistor ratio to large */
U8X8_C(0x081), /* set contrast */
U8X8_C(0x027), /* contrast value */
U8X8_C(0x0ac), /* indicator */
// 0x000, /* disable */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1701_mini12864_powersave0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a4), /* all pixel off, issue 142 */
U8X8_C(0x0af), /* display on */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1701_mini12864_powersave1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0ae), /* display off */
U8X8_C(0x0a5), /* enter powersafe: all pixel on, issue 142 */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1701_mini12864_flip0_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a0), /* segment remap a0/a1*/
U8X8_C(0x0c8), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const uint8_t u8x8_d_uc1701_mini12864_flip1_seq[] = {
U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
U8X8_C(0x0a1), /* segment remap a0/a1*/
U8X8_C(0x0c0), /* c0: scan dir normal, c8: reverse */
U8X8_END_TRANSFER(), /* disable chip */
U8X8_END() /* end of sequence */
};
static const u8x8_display_info_t u8x8_uc1701_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 5,
/* pre_chip_disable_wait_ns = */ 5,
/* reset_pulse_width_ms = */ 1,
/* post_reset_wait_ms = */ 6,
/* sda_setup_time_ns = */ 12,
/* sck_pulse_width_ns = */ 75, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 30,
/* write_pulse_width_ns = */ 40,
/* tile_width = */ 16, /* width of 16*8=128 pixel */
/* tile_hight = */ 8,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 4,
/* pixel_width = */ 128,
/* pixel_height = */ 64
};
uint8_t u8x8_d_uc1701_mini12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t x, c;
uint8_t *ptr;
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1701_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_init_seq);
break;
case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
if ( arg_int == 0 )
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_powersave0_seq);
else
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_powersave1_seq);
break;
case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
if ( arg_int == 0 )
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_flip0_seq);
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
else
{
u8x8_cad_SendSequence(u8x8, u8x8_d_uc1701_mini12864_flip1_seq);
u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
}
break;
#ifdef U8X8_WITH_SET_CONTRAST
case U8X8_MSG_DISPLAY_SET_CONTRAST:
u8x8_cad_StartTransfer(u8x8);
u8x8_cad_SendCmd(u8x8, 0x081 );
u8x8_cad_SendArg(u8x8, arg_int >> 2 ); /* uc1701 has range from 0 to 63 */
u8x8_cad_EndTransfer(u8x8);
break;
#endif
case U8X8_MSG_DISPLAY_DRAW_TILE:
u8x8_cad_StartTransfer(u8x8);
x = ((u8x8_tile_t *)arg_ptr)->x_pos;
x *= 8;
x += u8x8->x_offset;
u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
u8x8_cad_SendCmd(u8x8, 0x000 | ((x&15)));
u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));
c = ((u8x8_tile_t *)arg_ptr)->cnt;
c *= 8;
ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
/*
The following if condition checks the hardware limits of the uc1701
controller: It is not allowed to write beyond the display limits.
This is in fact an issue within flip mode.
bug: this check should be inside the while loop, see u8x8_d_pcd8544_84x48.c
*/
if ( c + x > 132u )
{
c = 132u;
c -= x;
}
do
{
u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */
arg_int--;
} while( arg_int > 0 );
u8x8_cad_EndTransfer(u8x8);
break;
default:
return 0;
}
return 1;
}

View File

@ -0,0 +1,205 @@
/*
u8x8_debounce.c
Key/button simple debounce algorithm (Addon for u8x8)
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static uint8_t u8x8_read_pin_state(u8x8_t *u8x8)
{
uint8_t i;
uint8_t pin_state;
pin_state = 255; /* be compatible with the setup of the default pin setup, which is 255 */
for( i = 0; i < U8X8_PIN_INPUT_CNT; i++ )
{
pin_state <<= 1;
/* the callback function should put the return value into this variable */
u8x8->gpio_result = 1;
u8x8_gpio_call(u8x8, U8X8_MSG_GPIO(i+U8X8_PIN_OUTPUT_CNT), 0);
pin_state |= u8x8->gpio_result & 1;
}
return pin_state;
}
/*
return 0 to U8X8_PIN_INPUT_CNT-1 if there is a difference
return U8X8_PIN_INPUT_CNT if there is no difference
*/
static uint8_t u8x8_find_first_diff(uint8_t a, uint8_t b)
{
uint8_t mask;
uint8_t i;
mask = 1;
i = U8X8_PIN_INPUT_CNT;
do
{
i--;
if ( (a & mask) != (b & mask) )
return i;
mask <<= 1;
} while( i > 0 );
return U8X8_PIN_INPUT_CNT;
}
/*
State A:
u8x8->debounce_last_pin_state == current_state
--> State A
u8x8->debounce_last_pin_state != current_state
--> u8x8->debounce_last_pin_state = current_state
--> State B + cnt
State B + cnt
--> state--
State B
u8x8->debounce_last_pin_state == current_state
--> keypress detected
--> State C
u8x8->debounce_last_pin_state != current_state
--> State A
State C
u8x8->debounce_last_pin_state == current_state
--> State C
u8x8->debounce_last_pin_state != current_state
--> State A
*/
#ifdef __unix__xxxxxx_THIS_IS_DISABLED
#include <stdio.h>
#include <stdlib.h>
uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
{
int c;
c = getc(stdin);
switch(c)
{
case 'n':
return U8X8_MSG_GPIO_MENU_NEXT;
case 'p':
return U8X8_MSG_GPIO_MENU_PREV;
case 's':
return U8X8_MSG_GPIO_MENU_SELECT;
case 'h':
return U8X8_MSG_GPIO_MENU_HOME;
case 'x':
exit(0);
default:
puts("press n, p, s, h or x");
break;
}
return 0;
}
#else /* __unix__ */
#define U8X8_DEBOUNCE_WAIT 2
/* do debounce and return a GPIO msg which indicates the event */
/* returns 0, if there is no event */
#if defined(__GNUC__) && !defined(__CYGWIN__)
# pragma weak u8x8_GetMenuEvent
#endif
uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
{
uint8_t pin_state;
uint8_t result_msg = 0; /* invalid message, no event */
pin_state = u8x8_read_pin_state(u8x8);
/* States A, B, C & D are encoded in the upper 4 bit*/
switch(u8x8->debounce_state)
{
case 0x00: /* State A, default state */
if ( u8x8->debounce_default_pin_state != pin_state )
{
//u8x8->debounce_last_pin_state = pin_state;
u8x8->debounce_state = 0x010 + U8X8_DEBOUNCE_WAIT;
}
break;
case 0x10: /* State B */
//if ( u8x8->debounce_last_pin_state != pin_state )
if ( u8x8->debounce_default_pin_state == pin_state )
{
u8x8->debounce_state = 0x00; /* back to state A */
}
else
{
/* keypress detected */
u8x8->debounce_last_pin_state = pin_state;
//result_msg = U8X8_MSG_GPIO_MENU_NEXT;
u8x8->debounce_state = 0x020 + U8X8_DEBOUNCE_WAIT; /* got to state C */
}
break;
case 0x20: /* State C */
if ( u8x8->debounce_last_pin_state != pin_state )
{
u8x8->debounce_state = 0x00; /* back to state A */
}
else
{
u8x8->debounce_state = 0x030; /* got to state D */
}
break;
case 0x30: /* State D */
/* wait until key release */
if ( u8x8->debounce_default_pin_state == pin_state )
{
u8x8->debounce_state = 0x00; /* back to state A */
result_msg = U8X8_MSG_GPIO(u8x8_find_first_diff(u8x8->debounce_default_pin_state, u8x8->debounce_last_pin_state)+U8X8_PIN_OUTPUT_CNT);
}
else
{
//result_msg = U8X8_MSG_GPIO_MENU_NEXT;
// maybe implement autorepeat here
}
break;
default:
u8x8->debounce_state--; /* count down, until there is a valid state */
break;
}
return result_msg;
}
#endif /* __unix__ */

View File

@ -0,0 +1,165 @@
/*
u8x8_display.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Abstraction layer for the graphics controller.
Main goal is the placement of a 8x8 pixel block (tile) on the display.
*/
#include "u8x8.h"
/*==========================================*/
/* internal library function */
/*
this is a helper function for the U8X8_MSG_DISPLAY_SETUP_MEMORY function.
It can be called within the display callback function to carry out the usual standard tasks.
*/
void u8x8_d_helper_display_setup_memory(u8x8_t *u8x8, const u8x8_display_info_t *display_info)
{
/* 1) set display info struct */
u8x8->display_info = display_info;
u8x8->x_offset = u8x8->display_info->default_x_offset;
}
/*
this is a helper function for the U8X8_MSG_DISPLAY_INIT function.
It can be called within the display callback function to carry out the usual standard tasks.
*/
void u8x8_d_helper_display_init(u8x8_t *u8x8)
{
/* 2) apply port directions to the GPIO lines and apply default values for the IO lines*/
u8x8_gpio_Init(u8x8);
u8x8_cad_Init(u8x8);
/* 3) do reset */
u8x8_gpio_SetReset(u8x8, 1);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms);
u8x8_gpio_SetReset(u8x8, 0);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms);
u8x8_gpio_SetReset(u8x8, 1);
u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->post_reset_wait_ms);
}
/*==========================================*/
/* official functions */
uint8_t u8x8_DrawTile(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr)
{
u8x8_tile_t tile;
tile.x_pos = x;
tile.y_pos = y;
tile.cnt = cnt;
tile.tile_ptr = tile_ptr;
return u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, 1, (void *)&tile);
}
/* should be implemented as macro */
void u8x8_SetupMemory(u8x8_t *u8x8)
{
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SETUP_MEMORY, 0, NULL);
}
void u8x8_InitDisplay(u8x8_t *u8x8)
{
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL);
}
void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable)
{
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_POWER_SAVE, is_enable, NULL);
}
void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode)
{
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, mode, NULL);
}
void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value)
{
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_CONTRAST, value, NULL);
}
void u8x8_RefreshDisplay(u8x8_t *u8x8)
{
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_REFRESH, 0, NULL);
}
void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf)
{
u8x8_tile_t tile;
uint8_t h;
tile.x_pos = 0;
tile.cnt = 1;
tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */
h = u8x8->display_info->tile_height;
tile.y_pos = 0;
do
{
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile);
tile.y_pos++;
} while( tile.y_pos < h );
}
void u8x8_ClearDisplay(u8x8_t *u8x8)
{
uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
u8x8_ClearDisplayWithTile(u8x8, buf);
}
void u8x8_FillDisplay(u8x8_t *u8x8)
{
uint8_t buf[8] = { 255, 255, 255, 255, 255, 255, 255, 255 };
u8x8_ClearDisplayWithTile(u8x8, buf);
}
void u8x8_ClearLine(u8x8_t *u8x8, uint8_t line)
{
uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
u8x8_tile_t tile;
if ( line < u8x8->display_info->tile_height )
{
tile.x_pos = 0;
tile.y_pos = line;
tile.cnt = 1;
tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */
u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/*
u8x8_gpio.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
void u8x8_gpio_call(u8x8_t *u8x8, uint8_t msg, uint8_t arg)
{
u8x8->gpio_and_delay_cb(u8x8, msg, arg, NULL);
}
/*
void u8x8_gpio_Delay(u8x8_t *u8x8, uint8_t msg, uint8_t dly)
{
u8x8->gpio_and_delay_cb(u8x8, msg, dly, NULL);
}
*/

View File

@ -0,0 +1,123 @@
/*
u8x8_input_value.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/*
return:
0: value is not changed (HOME/Break Button pressed)
1: value has been updated
*/
uint8_t u8x8_UserInterfaceInputValue(u8x8_t *u8x8, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post)
{
uint8_t height;
uint8_t y;
uint8_t width;
uint8_t x;
uint8_t local_value = *value;
uint8_t r;
uint8_t event;
/* calculate overall height of the input value box */
height = 1; /* button line */
height += u8x8_GetStringLineCnt(title);
/* calculate offset from top */
y = 0;
if ( height < u8x8_GetRows(u8x8) )
{
y = u8x8_GetRows(u8x8);
y -= height;
y /= 2;
}
/* calculate offset from left for the label */
x = 0;
width = u8x8_GetUTF8Len(u8x8, pre);
width += digits;
width += u8x8_GetUTF8Len(u8x8, post);
if ( width < u8x8_GetCols(u8x8) )
{
x = u8x8_GetCols(u8x8);
x -= width;
x /= 2;
}
/* render */
u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */
u8x8_SetInverseFont(u8x8, 0);
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title);
x += u8x8_DrawUTF8(u8x8, x, y, pre);
u8x8_DrawUTF8(u8x8, x+digits, y, post);
u8x8_SetInverseFont(u8x8, 1);
/* event loop */
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
for(;;)
{
event = u8x8_GetMenuEvent(u8x8);
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
{
*value = local_value;
r = 1;
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
{
r = 0;
break;
}
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP )
{
if ( local_value >= hi )
local_value = lo;
else
local_value++;
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
}
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN )
{
if ( local_value <= lo )
local_value = hi;
else
local_value--;
u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits));
}
}
u8x8_SetInverseFont(u8x8, 0);
return r;
}

View File

@ -0,0 +1,152 @@
/*
u8x8_message.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
uint8_t u8x8_draw_button_line(u8x8_t *u8x8, uint8_t y, uint8_t w, uint8_t cursor, const char *s)
{
uint8_t i;
uint8_t cnt;
uint8_t total;
uint8_t d;
uint8_t x;
cnt = u8x8_GetStringLineCnt(s);
/* calculate the width of the button */
total = 0;
for( i = 0; i < cnt; i++ )
{
total += u8x8_GetUTF8Len(u8x8, u8x8_GetStringLineStart(i, s));
}
total += (cnt-1); /* had one space between the buttons */
/* calculate the left offset */
d = 0;
if ( total < w )
{
d = w;
d -= total;
d /= 2;
}
/* draw the buttons */
x = d;
u8x8_SetInverseFont(u8x8, 0);
for( i = 0; i < cnt; i++ )
{
if ( i == cursor )
u8x8_SetInverseFont(u8x8, 1);
x+=u8x8_DrawUTF8(u8x8, x, y, u8x8_GetStringLineStart(i, s));
u8x8_SetInverseFont(u8x8, 0);
x+=u8x8_DrawUTF8(u8x8, x, y, " ");
}
/* return the number of buttons */
return cnt;
}
/*
title1: Multiple lines,separated by '\n'
title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart()
title3: Multiple lines,separated by '\n'
buttons: one more more buttons separated by '\n' and terminated with '\0'
*/
uint8_t u8x8_UserInterfaceMessage(u8x8_t *u8x8, const char *title1, const char *title2, const char *title3, const char *buttons)
{
uint8_t height;
uint8_t y;
uint8_t cursor = 0;
uint8_t button_cnt;
uint8_t event;
u8x8_SetInverseFont(u8x8, 0);
/* calculate overall height of the message box */
height = 1; /* button line */
height += u8x8_GetStringLineCnt(title1);
if ( title2 != NULL )
height ++;
height += u8x8_GetStringLineCnt(title3);
/* calculate offset from top */
y = 0;
if ( height < u8x8_GetRows(u8x8) )
{
y = u8x8_GetRows(u8x8);
y -= height;
y /= 2;
}
/* draw message box */
u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title1);
if ( title2 != NULL )
{
u8x8_DrawUTF8Line(u8x8, 0, y, u8x8_GetCols(u8x8), title2);
y++;
}
y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title3);
button_cnt = u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
for(;;)
{
event = u8x8_GetMenuEvent(u8x8);
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
return cursor+1;
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
break;
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP )
{
cursor++;
if ( cursor >= button_cnt )
cursor = 0;
u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
}
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN )
{
if ( cursor == 0 )
cursor = button_cnt;
cursor--;
u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons);
}
}
return 0;
}

View File

@ -0,0 +1,173 @@
/*
u8x8_selection_list.c
selection list with scroll option
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/*
increase the cursor position
*/
void u8sl_Next(u8sl_t *u8sl)
{
u8sl->current_pos++;
if ( u8sl->current_pos >= u8sl->total )
{
u8sl->current_pos = 0;
u8sl->first_pos = 0;
}
else
{
if ( u8sl->first_pos + u8sl->visible <= u8sl->current_pos + 1 )
{
u8sl->first_pos = u8sl->current_pos - u8sl->visible + 1;
}
}
}
void u8sl_Prev(u8sl_t *u8sl)
{
if ( u8sl->current_pos == 0 )
{
u8sl->current_pos = u8sl->total - 1;
u8sl->first_pos = 0;
if ( u8sl->total > u8sl->visible )
u8sl->first_pos = u8sl->total - u8sl->visible;
}
else
{
u8sl->current_pos--;
if ( u8sl->first_pos > u8sl->current_pos )
u8sl->first_pos = u8sl->current_pos;
}
}
void u8x8_DrawSelectionList(u8x8_t *u8x8, u8sl_t *u8sl, u8x8_sl_cb sl_cb, const void *aux)
{
uint8_t i;
for( i = 0; i < u8sl->visible; i++ )
{
sl_cb(u8x8, u8sl, i+u8sl->first_pos, aux);
}
}
/* selection list with string line */
void u8x8_sl_string_line_cb(u8x8_t *u8x8, u8sl_t *u8sl, uint8_t idx, const void *aux)
{
const char *s;
uint8_t row;
/* calculate offset from display upper border */
row = u8sl->y;
/* calculate target pos */
row += idx;
row -= u8sl->first_pos;
/* check whether this is the current cursor line */
if ( idx == u8sl->current_pos )
u8x8_SetInverseFont(u8x8, 1);
else
u8x8_SetInverseFont(u8x8, 0);
/* get the line from the array */
s = u8x8_GetStringLineStart(idx, (const char *)aux);
/* draw the line */
if ( s == NULL )
s = "";
u8x8_DrawUTF8Line(u8x8, u8sl->x, row, u8x8_GetCols(u8x8), s);
u8x8_SetInverseFont(u8x8, 0);
}
/*
title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n'
start_pos: default position for the cursor (starts with 1)
sl: string list (list of strings separated by \n)
returns 0 if user has pressed the home key
returns the selected line+1 if user has pressed the select key (e.g. 1 for the first line)
*/
uint8_t u8x8_UserInterfaceSelectionList(u8x8_t *u8x8, const char *title, uint8_t start_pos, const char *sl)
{
u8sl_t u8sl;
uint8_t event;
uint8_t title_lines;
if ( start_pos > 0 )
start_pos--;
u8sl.visible = u8x8_GetRows(u8x8);
u8sl.total = u8x8_GetStringLineCnt(sl);
u8sl.first_pos = 0;
u8sl.current_pos = start_pos;
u8sl.x = 0;
u8sl.y = 0;
//u8x8_ClearDisplay(u8x8); /* not required because all is 100% filled */
u8x8_SetInverseFont(u8x8, 0);
if ( title != NULL )
{
title_lines = u8x8_DrawUTF8Lines(u8x8, u8sl.x, u8sl.y, u8x8_GetCols(u8x8), title);
u8sl.y+=title_lines;
u8sl.visible-=title_lines;
}
if ( u8sl.current_pos >= u8sl.total )
u8sl.current_pos = u8sl.total-1;
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
for(;;)
{
event = u8x8_GetMenuEvent(u8x8);
if ( event == U8X8_MSG_GPIO_MENU_SELECT )
return u8sl.current_pos+1;
else if ( event == U8X8_MSG_GPIO_MENU_HOME )
return 0;
else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN )
{
u8sl_Next(&u8sl);
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
}
else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP )
{
u8sl_Prev(&u8sl);
u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl);
}
}
}

View File

@ -0,0 +1,147 @@
/*
u8x8_setup.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
/* universal dummy callback, which will be default for all callbacks */
uint8_t u8x8_dummy_cb(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
{
/* the dummy callback will not handle any message and will fail for all messages */
return 0;
}
static const u8x8_display_info_t u8x8_null_display_info =
{
/* chip_enable_level = */ 0,
/* chip_disable_level = */ 1,
/* post_chip_enable_wait_ns = */ 0,
/* pre_chip_disable_wait_ns = */ 0,
/* reset_pulse_width_ms = */ 0,
/* post_reset_wait_ms = */ 0,
/* sda_setup_time_ns = */ 0,
/* sck_pulse_width_ns = */ 0, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
/* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */
/* spi_mode = */ 0, /* active high, rising edge */
/* i2c_bus_clock_100kHz = */ 4,
/* data_setup_time_ns = */ 0,
/* write_pulse_width_ns = */ 0,
/* tile_width = */ 1, /* 8x8 */
/* tile_hight = */ 1,
/* default_x_offset = */ 0,
/* flipmode_x_offset = */ 0,
/* pixel_width = */ 8,
/* pixel_height = */ 8
};
/* a special null device */
uint8_t u8x8_d_null_cb(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_DISPLAY_SETUP_MEMORY:
u8x8_d_helper_display_setup_memory(u8x8, &u8x8_null_display_info);
break;
case U8X8_MSG_DISPLAY_INIT:
u8x8_d_helper_display_init(u8x8);
break;
}
/* the null device callback will succeed for all messages */
return 1;
}
/*
Description:
Setup u8x8
Args:
u8x8 An empty u8x8 structure
*/
void u8x8_SetupDefaults(u8x8_t *u8x8)
{
u8x8->display_info = NULL;
u8x8->display_cb = u8x8_dummy_cb;
u8x8->cad_cb = u8x8_dummy_cb;
u8x8->byte_cb = u8x8_dummy_cb;
u8x8->gpio_and_delay_cb = u8x8_dummy_cb;
u8x8->is_font_inverse_mode = 0;
u8x8->device_address = 0;
u8x8->utf8_state = 0; /* also reset by u8x8_utf8_init */
u8x8->bus_clock = 0; /* issue 769 */
u8x8->i2c_address = 255;
u8x8->debounce_default_pin_state = 255; /* assume all low active buttons */
#ifdef U8X8_USE_PINS
{
uint8_t i;
for( i = 0; i < U8X8_PIN_CNT; i++ )
u8x8->pins[i] = U8X8_PIN_NONE;
}
#endif
}
/*
Description:
Setup u8x8 and assign the callback function. The dummy
callback "u8x8_dummy_cb" can be used, if no callback is required.
This setup will not communicate with the display itself.
Use u8x8_InitDisplay() to send the startup code to the Display.
Args:
u8x8 An empty u8x8 structure
display_cb Display/controller specific callback function
cad_cb Display controller specific communication callback function
byte_cb Display controller/communication specific callback funtion
gpio_and_delay_cb Environment specific callback function
*/
void u8x8_Setup(u8x8_t *u8x8, u8x8_msg_cb display_cb, u8x8_msg_cb cad_cb, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
{
/* setup defaults and reset pins to U8X8_PIN_NONE */
u8x8_SetupDefaults(u8x8);
/* setup specific callbacks */
u8x8->display_cb = display_cb;
u8x8->cad_cb = cad_cb;
u8x8->byte_cb = byte_cb;
u8x8->gpio_and_delay_cb = gpio_and_delay_cb;
/* setup display info */
u8x8_SetupMemory(u8x8);
}

View File

@ -0,0 +1,170 @@
/*
u8x8_string.c
string line procedures
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
uint8_t u8x8_GetStringLineCnt(const char *str)
{
char e;
uint8_t line_cnt = 1;
if ( str == NULL )
return 0;
for(;;)
{
e = *str;
if ( e == '\0' )
break;
str++;
if ( e == '\n' )
line_cnt++;
}
return line_cnt;
}
/*
Assumes strings, separated by '\n' in "str".
Returns the string at index "line_idx". First strng has line_idx = 0
Example:
Returns "xyz" for line_idx = 1 with str = "abc\nxyz"
Support both UTF8 and normal strings.
*/
const char *u8x8_GetStringLineStart(uint8_t line_idx, const char *str )
{
char e;
uint8_t line_cnt = 1;
if ( line_idx == 0 )
return str;
for(;;)
{
e = *str;
if ( e == '\0' )
break;
str++;
if ( e == '\n' )
{
if ( line_cnt == line_idx )
return str;
line_cnt++;
}
}
return NULL; /* line not found */
}
/* copy until first '\n' or '\0' in str */
/* Important: There is no string overflow check, ensure */
/* that the destination buffer is large enough */
void u8x8_CopyStringLine(char *dest, uint8_t line_idx, const char *str)
{
if ( dest == NULL )
return;
str = u8x8_GetStringLineStart( line_idx, str );
if ( str != NULL )
{
for(;;)
{
if ( *str == '\n' || *str == '\0' )
break;
*dest = *str;
dest++;
str++;
}
}
*dest = '\0';
}
/*
Draw a string
Extend the string to size "w"
Center the string within "w"
return the size of the string
*/
uint8_t u8x8_DrawUTF8Line(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s)
{
uint8_t d, lw;
uint8_t cx, dx;
d = 0;
lw = u8x8_GetUTF8Len(u8x8, s);
if ( lw < w )
{
d = w;
d -=lw;
d /= 2;
}
cx = x;
dx = cx + d;
while( cx < dx )
{
u8x8_DrawUTF8(u8x8, cx, y, " ");
cx++;
}
cx += u8x8_DrawUTF8(u8x8, cx, y, s);
dx = x + w;
while( cx < dx )
{
u8x8_DrawUTF8(u8x8, cx, y, " ");
cx++;
}
cx -= x;
return cx;
}
/*
draw several lines at position x,y.
lines are stored in s and must be separated with '\n'.
lines can be centered with respect to "w"
if s == NULL nothing is drawn and 0 is returned
returns the number of lines in s
*/
uint8_t u8x8_DrawUTF8Lines(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s)
{
uint8_t i;
uint8_t cnt;
cnt = u8x8_GetStringLineCnt(s);
for( i = 0; i < cnt; i++ )
{
u8x8_DrawUTF8Line(u8x8, x, y, w, u8x8_GetStringLineStart(i, s));
y++;
}
return cnt;
}

View File

@ -0,0 +1,68 @@
/*
u8x8_u16toa.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
const char *u8x8_u16toap(char * dest, uint16_t v)
{
uint8_t pos;
uint8_t d;
uint16_t c;
c = 10000;
for( pos = 0; pos < 5; pos++ )
{
d = '0';
while( v >= c )
{
v -= c;
d++;
}
dest[pos] = d;
c /= 10;
}
dest[5] = '\0';
return dest;
}
/* v = value, d = number of digits */
const char *u8x8_u16toa(uint16_t v, uint8_t d)
{
static char buf[6];
d = 5-d;
return u8x8_u16toap(buf, v) + d;
}

View File

@ -0,0 +1,67 @@
/*
u8x8_u8toa.c
Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
Copyright (c) 2016, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8x8.h"
static const unsigned char u8x8_u8toa_tab[3] = { 100, 10, 1 } ;
const char *u8x8_u8toap(char * dest, uint8_t v)
{
uint8_t pos;
uint8_t d;
uint8_t c;
for( pos = 0; pos < 3; pos++ )
{
d = '0';
c = *(u8x8_u8toa_tab+pos);
while( v >= c )
{
v -= c;
d++;
}
dest[pos] = d;
}
dest[3] = '\0';
return dest;
}
/* v = value, d = number of digits */
const char *u8x8_u8toa(uint8_t v, uint8_t d)
{
static char buf[4];
d = 3-d;
return u8x8_u8toap(buf, v) + d;
}

View File

@ -0,0 +1,128 @@
Command comparison between ST7565, NT7534, IST3020, SPLC502, SSD1815, UC1701 and ST7567 display controller
Note: For multi-byte sequences, only the first byte is considered.
use monospaced font for this txt file
ST7565 ST7565 NT7534 UC1701 ST7567 IST3020 SPLC502 SSD1815 UC1601s ST7567
1.0a/2002 1.7c/2009 0.6/2007 1.2a/2016
0x000 00000000 Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col
...
0x00f 00001111 Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col Lo Col
0x010 00010000 Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col
...
0x01f 00011111 Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col Hi Col
0x020 00100000 Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio - Reg Ratio
...
0x023 00100011 Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio - Reg Ratio
0x024 00100100 Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Temp Ctl Reg Ratio
...
0x027 00100111 Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Res Ratio Temp Ctl Reg Ratio
0x028 00101000 Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl
...
0x02f 00101111 Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl Pwr Ctrl
0x030 00110000 - - PM Duty - - Rev. Line - - Adv Prg Ctl -
0x030 00110001 - - PM Duty - - Rev. Line - - Adv Prg Ctl -
0x030 00110010 - - PM Duty - - Rev. Line - - - -
... - - ... - - - -
0x037 00110111 - - PM Duty - - Rev. Line - - - -
0x038 00111000 - - PM Bias - - Rev. Line - - - -
... - - ... - - - -
0x03f 00111111 - - PM Bias - - Rev. Line - - - -
0x040 01000000 Start Line Start Line Start Line Scroll Line? Start Line DDRAM Line Start Line Start Line Scroll Line Start Line
...
0x07f 01111111 Start Line Start Line Start Line Scroll Line? Start Line DDRAM Line Start Line Start Line Scroll Line Start Line
0x080 10000000 - - - - - - - - - -
0x081 10000001 Contrast Contrast Contrast Contrast Contrast Contrast Contrast Contrast Contrast Contrast
0x082 10000010 - - Part. Mode - - - - - -
0x083 10000011 - - Part. Mode - - - - - -
0x084 10000100 - - Stop NL Inv - - - - - Partial Ctl Stop NL Inv
0x085 10000101 - - Start NL Inv - - - - - Partial Ctl Start NL Inv
0x086 10000110 - - - - - - - - Partial Ctl
0x087 10000111 - - - - - - - - Partial Ctl
0x088 10001000 - - - - - - - - Adr Ctl
...
0x08f 10001111 - - - - - - - - Adr Ctl
0x090 10010000 - - - - - - - -
0x091 10010001 - - - - - Offset Mode - -
0x092 10010010 - - - - - Offset Mode - -
0x093 10010011 - - - - - Offset Mode - -
...
0x09f 10011111 - - - - - - -
0x0a0 10100000 Seg Normal Seg Normal Seg Normal Seg Normal Seg Normal Seg Normal Seg Normal Seg Normal Frame Rate Seg Normal
0x0a1 10100001 Seg Reverse Seg Reverse Seg Reverse Seg Reverse Seg Reverse Seg Reverse Seg Reverse Seg Reverse Frame Rate Seg Reverse
0x0a2 10100010 1/9 bias 1/9 bias 1/9 bias 1/9 bias 1/9 bias Bias Bias 1/9 bias - 1/9 bias
0x0a3 10100011 1/7 bias 1/7 bias 1/7 bias 1/7 bias 1/7 bias Bias Bias 1/7 bias - 1/7 bias
0x0a4 10100100 Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op
0x0a5 10100101 All pt on All pt on All pt on All pt on All pt on All pt on All pt on All pt on All pt on All pt on
0x0a6 10100110 Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op Normal Op
0x0a7 10100111 Inverse Inverse Inverse Inverse Inverse Inverse Inverse Inverse Inverse Inverse
0x0a8 10101000 - - - - Stand-By - - - -
0x0a9 10101001 - - - - Sleep - - - -
0x0aa 10101010 - - - - - - - - - -
0x0ab 10101011 - - - - - - - - - -
0x0ac 10101100 Indic. On Sleep On Indic. On Indic. On Indic. On Indic. On Indic. On - -
0x0ad 10101101 Indic. Off Sleep Off Indic. Off Indic. Off Indic. Off Indic. Off Indic. Off - -
0x0ae 10101110 Disp Off Disp Off Disp Off Disp Off Disp Off Disp Off Disp Off Disp Off Disp Off Disp Off
0x0af 10101111 Disp On Disp On Disp On Disp On Disp On Disp On Disp On Disp On Disp On Disp On
0x0b0 10110000 Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr
...
0x0b7 10111111 Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr Page Adr
0x0c0 11000xxx Com Normal Com Normal Com Normal Com Normal Com Normal Com Normal Com Normal Com Normal LCD Map Com Normal
...
0x0c7 11000xxx Com Normal Com Normal Com Normal Com Normal Com Normal Com Normal Com Normal Com Normal LCD Map Com Normal
0x0c8 11001xxx Com Reverse Com Reverse Com Reverse Com Reverse Com Reverse Com Reverse Com Reverse Com Reverse - Com Reverse
...
0x0cf 11001xxx Com Reverse Com Reverse Com Reverse Com Reverse Com Reverse Com Reverse Com Reverse Com Reverse - Com Reverse
0x0d0 11010000 - - - - - - - - - -
0x0d1 11010001 - - - - - - - - - -
0x0d2 11010010 - - - - - - Drv Mode - - -
0x0d3 11010011 - - PM Line - - - - - - -
0x0d4 11010100 - - - - - - Test Mode - - -
0x0d5 11010101 - - - - - - Page Blink - - -
...
0x0df 11011111 - - - - - - - - - -
0x0e0 11100000 Start R-M-W Start R-M-W Start R-M-W Start R-M-W Start R-M-W Start R-M-W Start R-M-W Start R-M-W - Start R-M-W
0x0e1 11100001 - - - - - Reset Pwr Save - - - -
0x0e2 11100010 Reset Reset Reset Reset Reset Reset Reset Reset Reset Reset
0x0e3 11100011 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP
0x0e4 11100100 - - OSC Freq - - Rev Line Reset OSC Freq - - -
0x0e5 11100101 - - OSC Freq - - - OSC Freq - - -
0x0e6 11100110 - - DC/DC Freq - - - - - - -
0x0e7 11100111 - - - - - - - - - -
0x0e8 11101000 - - - - - - - - Bias Ratio -
...
0x0ed 11101101 - - - - - - - - Bias Ratio -
0x0ee 11101110 Stop R-M-W Stop R-M-W Stop R-M-W Stop R-M-W Stop R-M-W Stop R-M-W Stop R-M-W Bias Ratio Stop R-M-W
0x0ef 11101111 - - - - - - - - Bias Ratio -
0x0f0 11110000 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode - -
0x0f1 11110001 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode Com End -
0x0f2 11110010 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode Partial Start -
0x0f3 11110011 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode Partial End -
0x0f4 11110100 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode - -
0x0f5 11110101 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode - -
0x0f6 11110110 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode - -
0x0f7 11110111 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode - -
0x0f8 11111000 Test Mode Boost Level Test Mode - Boost Level Test Mode Test Mode Test Mode - Boost Level
0x0f9 11111001 Test Mode Test Mode Test Mode - - Test Mode Test Mode Test Mode - -
0x0fa 11111010 Test Mode Test Mode Test Mode Adv Ctrl0 - Test Mode Test Mode Test Mode - -
0x0fb 11111011 Test Mode Test Mode Test Mode Adv Ctrl1 - Test Mode Test Mode Test Mode - -
0x0fc 11111100 Test Mode Test Mode Test Mode Test Mode - Test Mode Test Mode Test Mode - -
0x0fd 11111101 Test Mode Test Mode Test Mode Test Mode - Test Mode Test Mode Test Mode - -
0x0fe 11111110 Test Mode Test Mode Test Mode Test Mode Test Mode Test Mode Test Mode Test Mode - Enter Ext.
0x0ff 11111111 Test Mode Test Mode Test Mode Test Mode Test Mode Test Mode Test Mode Test Mode - Leave Ext.
Conclusion (only from Datasheet documentation perspective)
* Command set of the ST7565 is fully included in NT7534 and UC1701
* Compared to ST7565, the UC1701 has an extra temperature control and
wrap around option (both in Adv Ctrl0)
* Compared to ST7565, the NT7534 has a partion mode (PM) option and
allows setting of several frequencies.
* Compared to ST7565, the ST7567 has an option to set the booster level
* Compared to ST7565, the SPLC502 has a drive power and page blinking options
* ST7565 2009: Version 1.7c (2009, http://www.newhavendisplay.com/app_notes/ST7565R.pdf)
includes the boost level/ratio command for the ST7565 and the indicator cmd is replaced by the sleep cmd

View File

@ -0,0 +1,18 @@
3=3 wire SPI
4=4 wire SPI
2=I2C
6=6800 8 bit parallel
8=8080 8 bit parallel
s=Arduino Standard Software Communication
pinMode and digitalWrite are used for communication
o=Arduino Optimized Software Communication
uC Specific low level functions for digital write and read
h=Hardware Communication with Standard Libs
TWI and SPI library
H=uC specific hardware communication
SSD1306 128x64
Arduino with ATMega328 (e.g. Uno) s2s3s4s6s8 h2h4
Arduino with AT91SAM3X8E (Due) s2s3s4s6s8 h2h4

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