olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
5.11k stars 1.05k forks source link

Request additional constructor for KS0108 ERM19264 display #2290

Open laserranger3000 opened 11 months ago

laserranger3000 commented 11 months ago

Hello,

I'd like to request an additional constructor for this display: https://www.buydisplay.com/download/manual/ERM19264-3_Series_Datasheet.pdf

The chip select works differently, using only 2 pins instead of 3. The rest should be identical to other products as far as I can see.

olikraus commented 11 months ago

hmm... i will add this to the current milestone, but i am not sure when I find time to work on this....

mpiernick commented 7 months ago

Hi, I just wrote something like this for the U8g2 Arduino. I don't know if this is the right way, it could probably be done better. This screen has CSA and CSB pins, there is no reset pin.

diff --git a/src/U8g2lib.h b/src/U8g2lib.h
index 0cf892f5..efbbcc99 100644
--- a/src/U8g2lib.h
+++ b/src/U8g2lib.h
@@ -22902,6 +22902,14 @@ class U8G2_KS0108_ERM19264_F : public U8G2 {
     u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset);
   }
 };
+//mpier...
+class U8G2_KS0108_CSAB19264_1 : public U8G2 {
+  public: U8G2_KS0108_CSAB19264_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 csa, uint8_t csb) : U8G2() {
+    u8g2_Setup_ks0108_csab19264_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, csa, csb, U8X8_PIN_NONE, U8X8_PIN_NONE);
+  }
+};
+//...mpier
 class U8G2_T7932_150X32_1 : public U8G2 {
   public: U8G2_T7932_150X32_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_t7932_150x32_1(&u8g2, rotation, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino);
diff --git a/src/U8x8lib.h b/src/U8x8lib.h
index d15fd618..f61b2191 100644
--- a/src/U8x8lib.h
+++ b/src/U8x8lib.h
@@ -7905,6 +7905,14 @@ class U8X8_KS0108_ERM19264 : public U8X8 {
     u8x8_SetPin_KS0108(getU8x8(), d0, d1, d2, d3, d4, d5, d6, d7, enable, dc, cs0, cs1, cs2, reset);
   }
 };
+//mpier...
+class U8X8_KS0108_CSAB19264 : public U8X8 {
+  public: U8X8_KS0108_CSAB19264(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 csa, uint8_t csb) : U8X8() {
+    u8x8_Setup(getU8x8(), u8x8_d_ks0108_csab19264, 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, csa, csb, U8X8_PIN_NONE, U8X8_PIN_NONE);
+  }
+};
+//...mpier
 class U8X8_T7932_150X32 : public U8X8 {
   public: U8X8_T7932_150X32(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_t7932_150x32, u8x8_cad_001, u8x8_byte_arduino_ks0108, u8x8_gpio_and_delay_arduino);
diff --git a/src/clib/u8g2.h b/src/clib/u8g2.h
index e0570888..49900b59 100644
--- a/src/clib/u8g2.h
+++ b/src/clib/u8g2.h
@@ -1469,6 +1469,9 @@ void u8g2_Setup_ks0108_128x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_ms
 void u8g2_Setup_ks0108_erm19264_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ks0108_erm19264_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ks0108_erm19264_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+//mpier...
+void u8g2_Setup_ks0108_csab19264_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+//...mpier
 void u8g2_Setup_t7932_150x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t7932_150x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t7932_150x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
diff --git a/src/clib/u8g2_d_setup.c b/src/clib/u8g2_d_setup.c
index c57c7875..14575d54 100644
--- a/src/clib/u8g2_d_setup.c
+++ b/src/clib/u8g2_d_setup.c
@@ -7227,6 +7227,17 @@ void u8g2_Setup_ks0108_erm19264_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
   buf = u8g2_m_24_8_f(&tile_buf_height);
   u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
 }
+//mpier...
+/* ks0108 1 */
+void u8g2_Setup_ks0108_csab19264_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
+{
+  uint8_t tile_buf_height;
+  uint8_t *buf;
+  u8g2_SetupDisplay(u8g2, u8x8_d_ks0108_csab19264, u8x8_cad_001, byte_cb, gpio_and_delay_cb);
+  buf = u8g2_m_24_8_1(&tile_buf_height);
+  u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
+}
+//...mpier
 /* t7932 */
 /* t7932 1 */
 void u8g2_Setup_t7932_150x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
diff --git a/src/clib/u8x8.h b/src/clib/u8x8.h
index 51d84f73..66617ac4 100644
--- a/src/clib/u8x8.h
+++ b/src/clib/u8x8.h
@@ -999,6 +999,9 @@ uint8_t u8x8_d_uc1638_192x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
 uint8_t u8x8_d_uc1638_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ks0108_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ks0108_erm19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+//mpier...
+uint8_t u8x8_d_ks0108_csab19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+//...mpier
 uint8_t u8x8_d_t7932_150x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* t7932 and hd44102 are compatible */
 uint8_t u8x8_d_hd44102_100x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* t7932 and hd44102 are compatible */
 uint8_t u8x8_d_sbn1661_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
diff --git a/src/clib/u8x8_d_ks0108.c b/src/clib/u8x8_d_ks0108.c
index 75197c48..586f6515 100644
--- a/src/clib/u8x8_d_ks0108.c
+++ b/src/clib/u8x8_d_ks0108.c
@@ -342,3 +342,111 @@ uint8_t u8x8_d_ks0108_erm19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
   return 1;
 }

+//mpier...
+/* CSA CSB left: 00, middle: 01, right: 10, no chip select: 11 */
+uint8_t u8x8_d_ks0108_csab19264(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, 0, NULL);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_init_seq);
+      u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 3, 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, 3, NULL);
+
+      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, 3, 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_ks0108_powersave0_seq);
+   u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 3, 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, 3, NULL);
+
+   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, 3, NULL);
+
+      }
+      else
+      {
+   u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 0, NULL);
+   u8x8_cad_SendSequence(u8x8, u8x8_d_ks0108_powersave1_seq);
+   u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 3, 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, 3, NULL);
+
+   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, 3, 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, 0, NULL);  // 3-->6, issue 631
+   u8x8_ks0108_out(u8x8, &v, arg_ptr);
+   u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 3, 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, 3, NULL);
+      }
+      if ( v.x < 24 )
+      {
+   u8x8->cad_cb(u8x8, U8X8_MSG_CAD_START_TRANSFER, 1, NULL); // 6-->3, // issue 631
+   u8x8_ks0108_out(u8x8, &v, arg_ptr);
+   u8x8->cad_cb(u8x8, U8X8_MSG_CAD_END_TRANSFER, 3, NULL);
+      }
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+//...mpier
+