From 23b162bfaac3b3604b693223558bbf9935b3634e Mon Sep 17 00:00:00 2001 From: olikraus Date: Wed, 14 Dec 2016 05:35:03 +0100 Subject: [PATCH] issue #104 --- cppsrc/U8g2lib.h | 12 +- cppsrc/U8x8lib.cpp | 207 +++++++++++++++-------- cppsrc/U8x8lib.h | 5 +- csrc/u8x8_byte.c | 2 +- sys/arduino/u8g2_page_buffer/FPS/FPS.ino | 7 +- tools/codebuild/codebuild.c | 2 +- 6 files changed, 152 insertions(+), 83 deletions(-) diff --git a/cppsrc/U8g2lib.h b/cppsrc/U8g2lib.h index 1fdf1fec..b60512d9 100644 --- a/cppsrc/U8g2lib.h +++ b/cppsrc/U8g2lib.h @@ -2144,37 +2144,37 @@ class U8G2_ST7565_NHD_C12832_F_8080 : public U8G2 { }; class U8G2_KS0108_128X64_1 : public U8G2 { public: U8G2_KS0108_128X64_1(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE) : U8G2() { - u8g2_Setup_ks0108_128x64_1(&u8g2, rotation, u8x8_byte_ks0108, u8x8_gpio_and_delay_arduino); + u8g2_Setup_ks0108_128x64_1(&u8g2, rotation, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino); u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset); } }; class U8G2_KS0108_128X64_2 : public U8G2 { public: U8G2_KS0108_128X64_2(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE) : U8G2() { - u8g2_Setup_ks0108_128x64_2(&u8g2, rotation, u8x8_byte_ks0108, u8x8_gpio_and_delay_arduino); + u8g2_Setup_ks0108_128x64_2(&u8g2, rotation, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino); u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset); } }; class U8G2_KS0108_128X64_F : public U8G2 { public: U8G2_KS0108_128X64_F(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE) : U8G2() { - u8g2_Setup_ks0108_128x64_f(&u8g2, rotation, u8x8_byte_ks0108, u8x8_gpio_and_delay_arduino); + u8g2_Setup_ks0108_128x64_f(&u8g2, rotation, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino); u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset); } }; class U8G2_KS0108_ERM19264_1 : public U8G2 { public: U8G2_KS0108_ERM19264_1(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE) : U8G2() { - u8g2_Setup_ks0108_erm19264_1(&u8g2, rotation, u8x8_byte_ks0108, u8x8_gpio_and_delay_arduino); + u8g2_Setup_ks0108_erm19264_1(&u8g2, rotation, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino); u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset); } }; class U8G2_KS0108_ERM19264_2 : public U8G2 { public: U8G2_KS0108_ERM19264_2(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE) : U8G2() { - u8g2_Setup_ks0108_erm19264_2(&u8g2, rotation, u8x8_byte_ks0108, u8x8_gpio_and_delay_arduino); + u8g2_Setup_ks0108_erm19264_2(&u8g2, rotation, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino); u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset); } }; class U8G2_KS0108_ERM19264_F : public U8G2 { public: U8G2_KS0108_ERM19264_F(const u8g2_cb_t *rotation, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE) : U8G2() { - u8g2_Setup_ks0108_erm19264_f(&u8g2, rotation, u8x8_byte_ks0108, u8x8_gpio_and_delay_arduino); + u8g2_Setup_ks0108_erm19264_f(&u8g2, rotation, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino); u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset); } }; diff --git a/cppsrc/U8x8lib.cpp b/cppsrc/U8x8lib.cpp index abf1e706..5477a4b1 100644 --- a/cppsrc/U8x8lib.cpp +++ b/cppsrc/U8x8lib.cpp @@ -276,74 +276,7 @@ extern "C" uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uin } } } - } - - -#ifdef NOTUSED - - data = (uint8_t *)arg_ptr; - while( arg_int > 0 ) - { - b = *data; - data++; - arg_int--; - - if ( b == 0 ) - { - /* do some high speed transfer for zero data */ - *arduino_data_port &= arduino_data_n_mask; - if ( takeover_edge == 0 ) - { - for( i = 0; i < 4; i++ ) - { - *arduino_clock_port |= arduino_clock_mask; - *arduino_clock_port &= arduino_clock_n_mask; - *arduino_clock_port |= arduino_clock_mask; - *arduino_clock_port &= arduino_clock_n_mask; - } - } - else - { - for( i = 0; i < 4; i++ ) - { - *arduino_clock_port &= arduino_clock_n_mask; - *arduino_clock_port |= arduino_clock_mask; - *arduino_clock_port &= arduino_clock_n_mask; - *arduino_clock_port |= arduino_clock_mask; - } - } - } - else - { - for( i = 0; i < 8; i++ ) - { - if ( b & 128 ) - *arduino_data_port |= arduino_data_mask; - else - *arduino_data_port &= arduino_data_n_mask; - b <<= 1; - - if ( takeover_edge == 0 ) - *arduino_clock_port |= arduino_clock_mask; - else - *arduino_clock_port &= arduino_clock_n_mask; - - /* AVR Architecture is very slow, extra call is not required */ - //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns); - - if ( takeover_edge != 0 ) - *arduino_clock_port |= arduino_clock_mask; - else - *arduino_clock_port &= arduino_clock_n_mask; - - /* AVR Architecture is very slow, extra call is not required */ - //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns); - } - } - } - -#endif - + } break; case U8X8_MSG_BYTE_INIT: @@ -591,7 +524,7 @@ extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, ui uint8_t *data; /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */ - /* so, it should be possible to used multiple displays with different pins */ + /* so, it should be possible to use multiple displays with different pins */ static volatile uint8_t *arduino_e_port; static volatile uint8_t arduino_e_mask; @@ -624,12 +557,14 @@ extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, ui /* AVR Architecture is very slow, extra call is not required */ - u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns); + //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns); + u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns); *arduino_e_port |= arduino_e_mask; /* AVR Architecture is very slow, extra call is not required */ - u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns); + //u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns); + u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_pulse_width_ns); } break; @@ -685,6 +620,136 @@ extern "C" uint8_t u8x8_byte_arduino_8bit_8080mode(u8x8_t *u8x8, uint8_t msg, ui #endif +/*=============================================*/ + +/* + replacement for a more faster u8x8_byte_ks0108 + in general u8x8_byte_ks0108 could be a fallback: + + uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) + { + return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr); + } + + + +*/ + +#ifndef __AVR_ARCH__ +#define __AVR_ARCH__ 0 +#endif + +#if !defined(U8X8_USE_PINS) + /* no pin information (very strange), so fallback */ +extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) +{ + return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr); +} + +#elif __AVR_ARCH__ == 4 || __AVR_ARCH__ == 5 || __AVR_ARCH__ == 51 || __AVR_ARCH__ == 6 + +/* this function completly replaces u8x8_byte_ks0108*/ +extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) +{ + uint8_t i, b; + uint8_t *data; + + /* the following static vars are recalculated in U8X8_MSG_BYTE_START_TRANSFER */ + /* so, it should be possible to use multiple displays with different pins */ + + static volatile uint8_t *arduino_e_port; + static volatile uint8_t arduino_e_mask; + static volatile uint8_t arduino_e_n_mask; + + static volatile uint8_t *arduino_data_port[8]; + static volatile uint8_t arduino_data_mask[8]; + static volatile uint8_t arduino_data_n_mask[8]; + + 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 & 1 ) + *arduino_data_port[i] |= arduino_data_mask[i]; + else + *arduino_data_port[i] &= arduino_data_n_mask[i]; + b >>= 1; + + } + + *arduino_e_port |= arduino_e_mask; + + + /* AVR Architecture is very slow, extra call is not required */ + u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->data_setup_time_ns); + + *arduino_e_port &= arduino_e_n_mask; + + /* AVR Architecture is very slow, extra call is not required */ + u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->write_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 */ + + /* 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: + 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); + + /* there is no consistency checking for u8x8->pins[U8X8_PIN_E] */ + + arduino_e_port = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_E])); + arduino_e_mask = digitalPinToBitMask(u8x8->pins[U8X8_PIN_E]); + arduino_e_n_mask = ~arduino_e_mask; + + /* there is no consistency checking for u8x8->pins[U8X8_PIN_D0] */ + + for( i = 0; i < 8; i++ ) + { + arduino_data_port[i] = portOutputRegister(digitalPinToPort(u8x8->pins[U8X8_PIN_D0+i])); + arduino_data_mask[i] = digitalPinToBitMask(u8x8->pins[U8X8_PIN_D0+i]); + arduino_data_n_mask[i] = ~arduino_data_mask[i]; + } + + 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; +} + +#else + /* fallback */ +extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) +{ + return u8x8_byte_ks0108(u8x8, msg,arg_int, arg_ptr); +} + +#endif + + + diff --git a/cppsrc/U8x8lib.h b/cppsrc/U8x8lib.h index e17cf78e..de9d00ee 100644 --- a/cppsrc/U8x8lib.h +++ b/cppsrc/U8x8lib.h @@ -84,6 +84,7 @@ extern "C" uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uin extern "C" uint8_t u8x8_byte_arduino_hw_spi(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr); extern "C" uint8_t u8x8_byte_arduino_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); extern "C" uint8_t u8x8_byte_arduino_2nd_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); +extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); void u8x8_SetPin_4Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset); void u8x8_SetPin_3Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset); @@ -852,13 +853,13 @@ class U8X8_ST7565_NHD_C12832_8080 : public U8X8 { }; class U8X8_KS0108_128X64 : public U8X8 { public: U8X8_KS0108_128X64(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE) : U8X8() { - u8x8_Setup(getU8x8(), u8x8_d_ks0108_128x64, u8x8_cad_001, u8x8_byte_ks0108, u8x8_gpio_and_delay_arduino); + u8x8_Setup(getU8x8(), u8x8_d_ks0108_128x64, u8x8_cad_001, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino); u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset); } }; class U8X8_KS0108_ERM19264 : public U8X8 { public: U8X8_KS0108_ERM19264(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE) : U8X8() { - u8x8_Setup(getU8x8(), u8x8_d_ks0108_erm19264, u8x8_cad_001, u8x8_byte_ks0108, u8x8_gpio_and_delay_arduino); + u8x8_Setup(getU8x8(), u8x8_d_ks0108_erm19264, u8x8_cad_001, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino); u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset); } }; diff --git a/csrc/u8x8_byte.c b/csrc/u8x8_byte.c index 82e23bd3..ed3d83f5 100644 --- a/csrc/u8x8_byte.c +++ b/csrc/u8x8_byte.c @@ -349,7 +349,7 @@ uint8_t u8x8_byte_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_p case U8X8_MSG_BYTE_INIT: /* disable chipselect */ u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level); - /* ensure that the enable signal is high */ + /* ensure that the enable signal is low */ u8x8_gpio_call(u8x8, U8X8_MSG_GPIO_E, 0); break; case U8X8_MSG_BYTE_SET_DC: diff --git a/sys/arduino/u8g2_page_buffer/FPS/FPS.ino b/sys/arduino/u8g2_page_buffer/FPS/FPS.ino index db8daf7e..9c73125c 100644 --- a/sys/arduino/u8g2_page_buffer/FPS/FPS.ino +++ b/sys/arduino/u8g2_page_buffer/FPS/FPS.ino @@ -179,7 +179,10 @@ 11 Dec 2016 U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI Uno Clip=25.8 Box=84.2 @=4.2 Pix=7.8 Old: no pixel optimization U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI Uno Clip=25.9 Box=84.1 @=4.3 Pix=8.3 Pixel (len=1) optimization - + + 14 Dec 2016 + U8G2_KS0108_128X64_1 Uno Clip=15.9 Box=28.0 @=3.9 Pix=6.9 + */ @@ -219,7 +222,7 @@ //U8G2_LD7032_60X32_1_4W_SW_I2C u8g2(U8G2_R0, /* clock=*/ 11, /* data=*/ 12, /* reset=*/ U8X8_PIN_NONE); // NOT TESTED! //U8G2_UC1701_EA_DOGS102_1_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //U8G2_UC1701_EA_DOGS102_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); -//U8G2_KS0108_128X64_1 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low! +U8G2_KS0108_128X64_1 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low! //U8G2_KS0108_ERM19264_1 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*dc=*/ 17, /*cs0=*/ 14, /*cs1=*/ 15, /*cs2=*/ U8X8_PIN_NONE, /* reset=*/ U8X8_PIN_NONE); // Set R/W to low! //U8G2_ST7920_192X32_1_8080 u8g2(U8G2_R0, 8, 9, 10, 11, 4, 5, 6, 7, /*enable=*/ 18, /*cs=*/ U8X8_PIN_NONE, /*dc=*/ 17, /*reset=*/ U8X8_PIN_NONE); //U8G2_ST7920_192X32_1_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18 /* A4 */ , /* data=*/ 16 /* A2 */, /* CS=*/ 17 /* A3 */, /* reset=*/ U8X8_PIN_NONE); diff --git a/tools/codebuild/codebuild.c b/tools/codebuild/codebuild.c index a1b52d60..ba167241 100644 --- a/tools/codebuild/codebuild.c +++ b/tools/codebuild/codebuild.c @@ -538,7 +538,7 @@ struct interface interface_list[] = { "", "u8x8_SetPin_KS0108", - "u8x8_byte_ks0108", + "u8x8_byte_arduino_ks0108", "u8x8_gpio_and_delay_arduino", "uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset = U8X8_PIN_NONE", "d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset",