From 25dfc154604a8b36db3505d4076dc04d48d424fb Mon Sep 17 00:00:00 2001 From: kraus Date: Sun, 7 Mar 2021 11:17:03 +0100 Subject: [PATCH] added ssd1320, issue 1351 --- ChangeLog | 2 +- csrc/u8x8.h | 1 + csrc/u8x8_d_ssd1320.c | 287 +++++++++++++++++++++++++++++++++ tools/codebuild/codebuild.c | 9 ++ tools/release/print_release.sh | 2 +- 5 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 csrc/u8x8_d_ssd1320.c diff --git a/ChangeLog b/ChangeLog index 6afc76a1..a2aa9659 100644 --- a/ChangeLog +++ b/ChangeLog @@ -245,7 +245,7 @@ https://github.com/olikraus/u8g2 ChangeLog * Added Lucida X11 fonts (issue 271) * Added several fonts from dafont.com (issue 1093) * Added 3-wire HW SPI (issue 1041) -2020-xx-xx v2.28.x olikraus@gmail.com +2020-12-28 v2.28.10 olikraus@gmail.com * Added Euro Symbol to _te fonts (issue 1321) * Added support for ST7528 (issue 986) * Added support for ST7571 (issue 1298) diff --git a/csrc/u8x8.h b/csrc/u8x8.h index f8056c2c..b0fec3a0 100644 --- a/csrc/u8x8.h +++ b/csrc/u8x8.h @@ -890,6 +890,7 @@ uint8_t u8x8_d_ssd1316_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void * uint8_t u8x8_d_ssd1317_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_ssd1318_128x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_ssd1318_128x96_xcp(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); +uint8_t u8x8_d_ssd1320_160x132(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_ssd1322_nhd_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_ssd1322_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_d_a2printer_384x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); diff --git a/csrc/u8x8_d_ssd1320.c b/csrc/u8x8_d_ssd1320.c new file mode 100644 index 00000000..9efa6d76 --- /dev/null +++ b/csrc/u8x8_d_ssd1320.c @@ -0,0 +1,287 @@ +/* + + u8x8_d_ssd1320.c + + Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) + + Copyright (c) 2020, 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. + + + https://github.com/olikraus/u8g2/issues/1351 + SSD1320: + 160 x 160 dot matrix + 16 gray scale + + Adapted from u8x8_d_ssd1322.c with the command set of the SSD1320 controller + "official" procedure is described here: https://github.com/olikraus/u8g2/wiki/internal + +*/ +#include "u8x8.h" + +static const uint8_t u8x8_d_ssd1320_cs1_160x132_nhd_powersave0_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0x0af), /* ssd1320: display on */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +static const uint8_t u8x8_d_ssd1320_cs1_160x132_nhd_powersave1_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0x0ae), /* ssd1320: display off */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + + +/* + input:32 + one tile (8 Bytes; 1 byte per column) + output: + Tile for SSD1320 (32 Bytes) + + The origin of the display seems to be in the upper right-hand corner. Therefore + compared to SSD1322, the order inside each byte is swapped. +*/ + +static uint8_t u8x8_ssd1320_to32_dest_buf[32]; + +static uint8_t *u8x8_ssd1320_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_ssd1320_to32_dest_buf; + dest += j; + a =*ptr; + ptr++; + b = *ptr; + ptr++; + for( i = 0; i < 8; i++ ) + { + v = 0; + if ( a&1 ) v |= 0x0f; + if ( b&1 ) v |= 0xf0; + *dest = v; + dest+=4; + a >>= 1; + b >>= 1; + } + } + + return u8x8_ssd1320_to32_dest_buf; +} + + +uint8_t u8x8_d_ssd1320_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_ssd1320_256x64_init_seq); + break; + */ + case U8X8_MSG_DISPLAY_SET_POWER_SAVE: + if ( arg_int == 0 ) + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_cs1_160x132_nhd_powersave0_seq); + else + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_cs1_160x132_nhd_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 ); /* ssd1320 has range from 1 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; + y = (((u8x8_tile_t *)arg_ptr)->y_pos); + x += u8x8->x_offset; + + y *= 8; + + + u8x8_cad_SendCmd(u8x8, 0x022 ); /* 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, 0x021 ); /* set column address */ + u8x8_cad_SendArg(u8x8, x ); /* start */ + u8x8_cad_SendArg(u8x8, x+3 ); /* end */ + + u8x8_cad_SendData(u8x8, 32, u8x8_ssd1320_8to32(u8x8, ptr)); + + ptr += 8; + x += 4; + 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_ssd1320_cs1_160x132_nhd_flip0_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0x0a0), /* remap */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +static const uint8_t u8x8_d_ssd1320_cs1_160x132_nhd_flip1_seq[] = { + U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ + U8X8_C(0x0a1), /* remap */ + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + +static const u8x8_display_info_t u8x8_d_ssd1320_cs1_160x132_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, /* ssd1320: 2 us */ + /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */ + /* sda_setup_time_ns = */ 50, /* ssd1320: 15ns, but cycle time is 100ns, so use 100/2 */ + /* sck_pulse_width_ns = */ 50, /* ssd1320: 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, /* ssd1320: cycle time is 300ns, so use 300/2 = 150 */ + /* tile_width = */ 20, /* 160 pixel, so we require 20 bytes for this */ + /* tile_hight = */ 17, + /* 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 = */ 160, + /* pixel_height = */ 132 +}; + +// initialisation sequence from the Arduino Library +// (see https://github.com/sparkfun/SparkFun_SSD1320_OLED_Arduino_Library) +static const uint8_t u8x8_d_ssd1320_cs1_160x132_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_CA(0xd5, 0xC2), /* set display clock divide ratio/oscillator frequency (set clock as 80 frames/sec) */ + U8X8_CA(0xa8, 0x1f), /* multiplex ratio 1/64 Duty (0x0F~0x3F) */ + U8X8_CA(0xa2, 0x00), /* display start line */ + + U8X8_C(0xa0), /* Set Segment Re-Map: column address 0 mapped to SEG0 CS1 */ + // U8X8_C(0xa1), /* Set Segment Re-Map: column address 0 mapped to SEG0 CS2 */ + + U8X8_C(0xc8), /* Set COM Output Scan Direction: normal mode CS1 */ + // U8X8_C(0xc0), /* Set COM Output Scan Direction: normal mode CS2 */ + + U8X8_CA(0xd3, 0x72), /* CS1 */ + // U8X8_CA(0xd3, 0x92), /* CS2 */ + + U8X8_CA(0xda, 0x12), /* Set SEG Pins Hardware Configuration: */ + U8X8_CA(0x81, 0x5a), /* contrast */ + U8X8_CA(0xd9, 0x22), /* Set Phase Length */ + U8X8_CA(0xdb, 0x30), /* VCOMH Deselect Level */ + U8X8_CA(0xad, 0x10), /* Internal IREF Enable */ + U8X8_CA(0x20, 0x00), /* Memory Addressing Mode: Horizontal */ + U8X8_CA(0x8d, 0x01), /* disable internal charge pump 1 */ + U8X8_CA(0xac, 0x00), /* disable internal charge pump 2 */ + U8X8_C(0xa4), /* display on */ + U8X8_C(0xa6), /* normal display */ + + U8X8_DLY(1), /* delay 2ms */ + + U8X8_END_TRANSFER(), /* disable chip */ + U8X8_END() /* end of sequence */ +}; + + +uint8_t u8x8_d_ssd1320_160x132(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_d_ssd1320_cs1_160x132_display_info); + break; + + case U8X8_MSG_DISPLAY_INIT: + u8x8_d_helper_display_init(u8x8); + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_cs1_160x132_init_seq); + break; + + case U8X8_MSG_DISPLAY_SET_FLIP_MODE: + if ( arg_int == 0 ){ + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_cs1_160x132_nhd_flip0_seq); + u8x8->x_offset = u8x8->display_info->default_x_offset; + } + else{ + u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_cs1_160x132_nhd_flip1_seq); + u8x8->x_offset = u8x8->display_info->flipmode_x_offset; + } + break; + + default: + return u8x8_d_ssd1320_common(u8x8, msg, arg_int, arg_ptr); + } + return 1; +} + diff --git a/tools/codebuild/codebuild.c b/tools/codebuild/codebuild.c index 9870a611..f781b8b0 100644 --- a/tools/codebuild/codebuild.c +++ b/tools/codebuild/codebuild.c @@ -1437,6 +1437,15 @@ struct controller controller_list[] = { NULL } } }, + { + "ssd1320", 20, 17, "u8g2_ll_hvline_vertical_top_lsb", "u8x8_cad_011", "", COM_4WSPI|COM_3WSPI|COM_6800|COM_8080, + "Requires U8G2_16BIT (see u8g2.h)", /* is_generate_u8g2_class= */ 1, + { + { "160x132" }, + { NULL } + } + }, + { "ssd1322", 32, 8, "u8g2_ll_hvline_vertical_top_lsb", "u8x8_cad_011", "", COM_4WSPI|COM_3WSPI|COM_6800|COM_8080, "Requires U8G2_16BIT (see u8g2.h)", /* is_generate_u8g2_class= */ 1, diff --git a/tools/release/print_release.sh b/tools/release/print_release.sh index d7ef41fa..32b78dc3 100755 --- a/tools/release/print_release.sh +++ b/tools/release/print_release.sh @@ -1,2 +1,2 @@ # without 'v' prefix -echo -n "2.28.9" +echo -n "2.28.10"