Browse Source

update:更新u8g2至最新版

Dozingfiretruck 2 years ago
parent
commit
06db7a23b5
92 changed files with 12267 additions and 1096 deletions
  1. 941 0
      components/u8g2/mui.c
  2. 609 0
      components/u8g2/mui.h
  3. 2243 0
      components/u8g2/mui_u8g2.c
  4. 307 0
      components/u8g2/mui_u8g2.h
  5. 411 14
      components/u8g2/u8g2.h
  6. 198 162
      components/u8g2/u8g2_d_memory.c
  7. 771 43
      components/u8g2/u8g2_d_setup.c
  8. 210 2
      components/u8g2/u8g2_font.c
  9. 646 422
      components/u8g2/u8g2_fonts.c
  10. 1 1
      components/u8g2/u8g2_line.c
  11. 5 5
      components/u8g2/u8g2_polygon.c
  12. 2 1
      components/u8g2/u8g2_setup.c
  13. 60 20
      components/u8g2/u8x8.h
  14. 1 0
      components/u8g2/u8x8_byte.c
  15. 2 2
      components/u8g2/u8x8_d_a2printer.c
  16. 200 0
      components/u8g2/u8x8_d_custom.c
  17. 206 0
      components/u8g2/u8x8_d_gp1247ai.c
  18. 212 0
      components/u8g2/u8x8_d_gp1287ai.c
  19. 182 0
      components/u8g2/u8x8_d_gp1294ai.c
  20. 86 3
      components/u8g2/u8x8_d_gu800.c
  21. 2 2
      components/u8g2/u8x8_d_hd44102.c
  22. 1 1
      components/u8g2/u8x8_d_il3820_296x128.c
  23. 1 1
      components/u8g2/u8x8_d_ist3020.c
  24. 280 0
      components/u8g2/u8x8_d_ist3088.c
  25. 1 1
      components/u8g2/u8x8_d_ist7920.c
  26. 2 2
      components/u8g2/u8x8_d_ks0108.c
  27. 76 4
      components/u8g2/u8x8_d_lc7981.c
  28. 163 4
      components/u8g2/u8x8_d_ld7032_60x32.c
  29. 7 7
      components/u8g2/u8x8_d_ls013b7dh03.c
  30. 4 4
      components/u8g2/u8x8_d_max7219.c
  31. 1 1
      components/u8g2/u8x8_d_pcd8544_84x48.c
  32. 1 1
      components/u8g2/u8x8_d_pcf8812.c
  33. 1 1
      components/u8g2/u8x8_d_pcf8814_hx1230.c
  34. 255 0
      components/u8g2/u8x8_d_s1d15300.c
  35. 5 1
      components/u8g2/u8x8_d_s1d15721.c
  36. 1 1
      components/u8g2/u8x8_d_s1d15e06.c
  37. 1 1
      components/u8g2/u8x8_d_sbn1661.c
  38. 185 2
      components/u8g2/u8x8_d_sed1330.c
  39. 1 1
      components/u8g2/u8x8_d_sh1106_64x32.c
  40. 1 1
      components/u8g2/u8x8_d_sh1106_72x40.c
  41. 313 5
      components/u8g2/u8x8_d_sh1107.c
  42. 74 0
      components/u8g2/u8x8_d_sh1108.c
  43. 7 4
      components/u8g2/u8x8_d_sh1122.c
  44. 68 4
      components/u8g2/u8x8_d_ssd1305.c
  45. 3 3
      components/u8g2/u8x8_d_ssd1306_128x32.c
  46. 82 3
      components/u8g2/u8x8_d_ssd1306_128x64_noname.c
  47. 1 1
      components/u8g2/u8x8_d_ssd1306_64x32.c
  48. 1 1
      components/u8g2/u8x8_d_ssd1306_64x48.c
  49. 1 1
      components/u8g2/u8x8_d_ssd1306_72x40.c
  50. 1 1
      components/u8g2/u8x8_d_ssd1306_96x16.c
  51. 328 0
      components/u8g2/u8x8_d_ssd1306_96x40.c
  52. 3 3
      components/u8g2/u8x8_d_ssd1309.c
  53. 97 1
      components/u8g2/u8x8_d_ssd1316.c
  54. 1 1
      components/u8g2/u8x8_d_ssd1317.c
  55. 1 1
      components/u8g2/u8x8_d_ssd1318.c
  56. 266 38
      components/u8g2/u8x8_d_ssd1320.c
  57. 122 2
      components/u8g2/u8x8_d_ssd1322.c
  58. 2 2
      components/u8g2/u8x8_d_ssd1325.c
  59. 1 1
      components/u8g2/u8x8_d_ssd1326.c
  60. 96 5
      components/u8g2/u8x8_d_ssd1327.c
  61. 2 2
      components/u8g2/u8x8_d_ssd1329.c
  62. 538 0
      components/u8g2/u8x8_d_ssd1362.c
  63. 1 1
      components/u8g2/u8x8_d_ssd1606_172x72.c
  64. 1 1
      components/u8g2/u8x8_d_ssd1607_200x200.c
  65. 1 1
      components/u8g2/u8x8_d_st7511.c
  66. 54 46
      components/u8g2/u8x8_d_st75160.c
  67. 221 8
      components/u8g2/u8x8_d_st75256.c
  68. 3 4
      components/u8g2/u8x8_d_st7528.c
  69. 1 1
      components/u8g2/u8x8_d_st75320.c
  70. 179 0
      components/u8g2/u8x8_d_st7539.c
  71. 13 13
      components/u8g2/u8x8_d_st7565.c
  72. 524 12
      components/u8g2/u8x8_d_st7567.c
  73. 7 4
      components/u8g2/u8x8_d_st7571.c
  74. 246 0
      components/u8g2/u8x8_d_st7586s_jlx320160.c
  75. 256 0
      components/u8g2/u8x8_d_st7586s_jlx384160.c
  76. 1 1
      components/u8g2/u8x8_d_st7588.c
  77. 114 14
      components/u8g2/u8x8_d_st7920.c
  78. 1 2
      components/u8g2/u8x8_d_stdio.c
  79. 87 6
      components/u8g2/u8x8_d_t6963.c
  80. 2 2
      components/u8g2/u8x8_d_uc1601.c
  81. 1 1
      components/u8g2/u8x8_d_uc1604.c
  82. 4 4
      components/u8g2/u8x8_d_uc1608.c
  83. 1 1
      components/u8g2/u8x8_d_uc1609.c
  84. 1 1
      components/u8g2/u8x8_d_uc1610.c
  85. 5 5
      components/u8g2/u8x8_d_uc1611.c
  86. 1 1
      components/u8g2/u8x8_d_uc1617.c
  87. 76 2
      components/u8g2/u8x8_d_uc1638.c
  88. 1 1
      components/u8g2/u8x8_d_uc1701_dogs102.c
  89. 1 1
      components/u8g2/u8x8_d_uc1701_mini12864.c
  90. 1 1
      components/u8g2/u8x8_debounce.c
  91. 3 2
      components/u8g2/u8x8_display.c
  92. 170 170
      components/u8g2/u8x8_fonts.c

+ 941 - 0
components/u8g2/mui.c

@@ -0,0 +1,941 @@
+/*
+
+  mui.c
+  
+  Monochrome minimal user interface: Core library.
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2021, 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.  
+
+  
+
+  "mui.c" is a graphical user interface, developed as part of u8g2.
+  However "mui.c" is independent of u8g2 and can be used without u8g2 code.
+  The glue code between "mui.c" and u8g2 is located in "mui_u8g2.c"
+
+  c: cmd
+  i:  ID0
+  j: ID1
+  xy: Position (x and y)
+  /text/: some text. The text can start with any delimiter (except 0 and |), but also has to end with the same delimiter
+  a: Single char argument
+  u: Single char argument with the user interface form number
+
+  "Uu" the interface                                                    --> no ID
+  
+  Manual ID:
+  "Fijxy"  Generic field: Places field with id ii at x/y        --> ID=ij
+  "Bijxy/text/"   Generic field (Button) with Text   --> ID=ij
+  "Tiixya/text/"  Generic field with argument and text --> ID = ij
+  "Aiixya"
+  
+  Fixed ID:
+  "Si" the style                                                        --> ID=@i
+  "Lxy/labeltext/"  Places a text at the specified position, field with   -     -> ID=.L, .l
+  "Gxyu/menutext/"  Go to the specified menu without placing the user interface form on the stack       --> ID=.G, .g
+  
+  
+  cijxy
+  cijxy/text/
+  cijxya/text/
+  
+  cxy/text/
+  cxya/text/
+  
+*/
+
+
+
+#include "mui.h"
+
+
+
+
+
+//#define mui_get_fds_char(s) ((uint8_t)(*s))
+
+//#include <stdio.h>
+//#define MUI_DEBUG(...) printf(__VA_ARGS__)
+#define MUI_DEBUG(...)
+
+uint8_t mui_get_fds_char(fds_t *s)
+{
+  //return (uint8_t)(*s);
+  return (uint8_t)mui_pgm_read(s);
+}
+
+
+/*
+  s must point to a valid command within FDS
+*/
+static size_t mui_fds_get_cmd_size_without_text(fds_t *s) MUI_NOINLINE;
+static size_t mui_fds_get_cmd_size_without_text(fds_t *s)
+{
+  uint8_t c = mui_get_fds_char(s);
+  c &= 0xdf; /* consider upper and lower case */
+  switch(c)
+  {
+    case 'U': return 2;         // User Form: CMD  (1 Byte), Form-Id (1 Byte)
+    case 'S': return 2;         // Style: CMD (1 Byte), Style Id (1 Byte)
+    case 'D': return 3;         // Data within Text: CMD (1 Byte), ID (2 Bytes), Text (does not count here)
+    case 'Z': return 3;         // Zero field without x, y, arg & text: CMD (1 Byte), ID (2 Bytes)
+    case 'F': return 5;         // Field without arg & text: CMD (1 Byte), ID (2 Bytes), X, Y
+    case 'B': return 5;         // Field with text: CMD (1 Byte), ID (2 Bytes), X, Y, Text (does not count here)
+    case 'T': return 6;         // Field with arg & text: CMD (1 Byte), ID (2 Bytes), X, Y, Arg, Text (does not count here)
+    case 'A': return 6;         // Field with arg (no text): CMD (1 Byte), ID (2 Bytes), X, Y, Arg, Text
+    case 'L': return 3;          // Text Label: CMD (1 Byte), X, Y (same as 'B' but with fixed ID '.L', MUIF_LABEL, MUI_LABEL)
+    case 'G': return 4;         // Goto Btutton: CMD (1Byte), X, Y, Arg, Text  (same as 'T' but with fixed ID '.G', MUIF_GOTO, MUI_GOTO)
+    case 0: return 0;
+  }
+  return 1;
+}
+
+
+
+/*
+  s must point to the string delimiter start: first '/' for "B00ab/ok/"
+    - '/' actually is 0xff
+    - return the total size of the string, including the delimiter
+    - copies the content of the string ("ok") to the ui text buffer
+
+*/
+static size_t mui_fds_parse_text(mui_t *ui, fds_t *s)
+{
+  uint8_t i = 0;
+  ui->delimiter = mui_get_fds_char(s);
+  uint8_t c;
+  fds_t *t = s;
+  
+  //printf("mui_fds_parse_text del=%d\n", delimiter);
+#ifdef MUI_CHECK_EOFDS
+  if ( ui->delimiter == 0 )
+    return 0;
+#endif 
+  t++;
+  for( ;; )
+  {
+    c = mui_get_fds_char(t);
+  //printf("mui_fds_parse_text i=%d, c=%c\n", i, c);
+#ifdef MUI_CHECK_EOFDS
+    if ( c == 0 )
+      break;
+#endif 
+    if ( c == ui->delimiter )
+    {
+      t++;
+      break;
+    }
+    if ( i < MUI_MAX_TEXT_LEN )
+    {
+      ui->text[i++] = c;
+    }
+    t++;
+  }
+  ui->text[i] = '\0' ;
+  return t-s;
+}
+
+/*
+  get the first token within a text argument.
+  The text argument may look like this:
+    "B00ab/banana|apple|peach|cherry/"
+  The outer delimiter "/" is not fixed and can be any char except "|" and "\0"
+  The inner delimiter "|" is fixed. It must be the pipe symbol.
+  This function will place "banana" into ui->text if the result is not 0
+
+  if ( mui_fds_first_token(ui) )
+  {
+    do 
+    {
+      // handle token in ui->text
+    } while ( mui_fds_next_token(ui) )
+  }
+
+*/
+
+uint8_t mui_fds_first_token(mui_t *ui)
+{
+  ui->token = ui->fds;
+  ui->token += mui_fds_get_cmd_size_without_text(ui->fds);
+  ui->delimiter = mui_get_fds_char(ui->token);
+  ui->token++;  // place ui->token on the first char of the token
+  return mui_fds_next_token(ui);
+}
+
+/*
+  The inner token delimiter "|" is fixed. It must be the pipe symbol.
+*/
+uint8_t mui_fds_next_token(mui_t *ui)
+{
+  uint8_t c;
+  uint8_t i = 0;
+  // printf("mui_fds_next_token: call, ui->token=%p\n", ui->token);
+  for( ;; )
+  {
+    c = mui_get_fds_char(ui->token);
+    // printf("mui_fds_next_token: i=%d c=%c\n", i, c);
+#ifdef MUI_CHECK_EOFDS
+    if ( c == 0 )
+      break;
+#endif 
+    if ( c == ui->delimiter )
+      break;
+    if ( c == '|'  )
+    {
+      ui->token++;  // place ui->token on the first char of the next token
+      break;
+    }
+    
+    if ( i < MUI_MAX_TEXT_LEN )
+    {
+      ui->text[i++] = c;
+    }
+    
+    ui->token++;
+  }
+  ui->text[i] = '\0' ;
+  if ( i == 0 )
+    return 0;   // no further token found
+  return 1;  // token placed in ui->text
+}
+
+/*
+  find nth token ('|' delimiter), return 0 if n exceeds the number of tokens, 1 otherwise
+  the result is stored in ui->text
+*/
+uint8_t mui_fds_get_nth_token(mui_t *ui, uint8_t n)
+{  
+  // printf("mui_fds_get_nth_token: call, n=%d\n", n);
+  if ( mui_fds_first_token(ui) )
+  {
+    do 
+    {
+      if ( n == 0 )
+      {
+        // printf("mui_fds_get_nth_token: found");
+        return 1;
+      }
+      n--;
+    } while ( mui_fds_next_token(ui) );
+  }
+  //printf("mui_fds_get_nth_token: NOT found\n");
+  return 0;
+}
+
+uint8_t mui_fds_get_token_cnt(mui_t *ui)
+{
+  uint8_t n = 0;
+  if ( mui_fds_first_token(ui) )
+  {
+    do 
+    {
+      n++;
+    } while ( mui_fds_next_token(ui) );
+  }
+  return n;
+}
+
+
+#define mui_fds_is_text(c) ( (c) == 'U' || (c) == 'S' || (c) == 'F' || (c) == 'A' || (c) == 'Z' ? 0 : 1 )
+
+/*
+  s must point to a valid command within FDS
+  return
+    The complete length of the command (including any text part)
+  sideeffect:
+    Any existing text part will be copied into ui->text
+    ui->text will be assigned to empty string if there is no text argument
+*/
+static size_t mui_fds_get_cmd_size(mui_t *ui, fds_t *s) MUI_NOINLINE;
+static size_t mui_fds_get_cmd_size(mui_t *ui, fds_t *s)
+{
+  size_t l = mui_fds_get_cmd_size_without_text(s);
+  uint8_t c = mui_get_fds_char(s);
+ ui->text[0] = '\0' ;   /* always reset the text buffer */
+ if ( mui_fds_is_text(c) )
+  {
+    l += mui_fds_parse_text(ui, s+l);
+  }
+  return l;
+}
+
+
+/*
+  mui_Init() will setup the menu system but will not activate or display anything.
+  Use mui_GotoForm() after this command, then use mui_Draw() to draw the menu on a display.
+*/
+void mui_Init(mui_t *ui, void *graphics_data, fds_t *fds, muif_t *muif_tlist, size_t muif_tcnt)
+{
+  memset(ui, 0, sizeof(mui_t));
+  ui->root_fds = fds;
+  //ui->current_form_fds = NULL;   // not required, because there was a memset before
+  ui->muif_tlist = muif_tlist;
+  ui->muif_tcnt = muif_tcnt;
+  ui->graphics_data = graphics_data;
+}
+
+int mui_find_uif(mui_t *ui, uint8_t id0, uint8_t id1)
+{
+  size_t i;
+  for( i = 0; i < ui->muif_tcnt; i++ )
+  {
+    /*
+      if ( ui->muif_tlist[i].id0 == id0 )
+        if ( ui->muif_tlist[i].id1 == id1 )
+          return i;
+    */
+      if ( muif_get_id0(ui->muif_tlist+i) == id0 )
+        if ( muif_get_id1(ui->muif_tlist+i) == id1 )
+          return i;
+  }
+  return -1;
+}
+
+
+/*
+  assumes a valid position in ui->fds and calculates all the other variables
+  some fields are always calculated like the ui->cmd and ui->len field
+  other member vars are calculated only if the return value is 1
+  will return 1 if the field id was found.
+  will return 0 if the field id was not found in uif or if ui->fds points to something else than a field
+*/
+static uint8_t mui_prepare_current_field(mui_t *ui) MUI_NOINLINE;
+static uint8_t mui_prepare_current_field(mui_t *ui)
+{
+  int muif_tidx;
+
+  ui->uif = NULL;
+  ui->dflags = 0;    
+  ui->id0 = 0;
+  ui->id1 = 0;
+  ui->arg = 0;
+
+  /* calculate the length of the command and copy the text argument */
+  /* this will also clear the text in cases where there is no text argument */
+  ui->len = mui_fds_get_cmd_size(ui, ui->fds); 
+  //printf("mui_prepare_current_field len=%d\n", ui->len);
+
+  /* get the command and check whether end of form is reached */
+  ui->cmd = mui_get_fds_char(ui->fds);
+  //printf("mui_prepare_current_field cmd='%c' len=%d\n", ui->cmd, ui->len);
+  
+  /* Copy the cmd also to second id value. This is required for some commands, others will overwrite this below */
+  ui->id1 = ui->cmd;
+  
+  /* now make the command uppercase so that both, upper and lower case are considered */
+  ui->cmd &= 0xdf; /* consider upper and lower case */
+  
+  if ( ui->cmd == 'U' || ui->cmd == 0 )
+    return 0;
+
+  /* calculate the dynamic flags */
+  if ( ui->fds == ui->cursor_focus_fds )
+    ui->dflags |= MUIF_DFLAG_IS_CURSOR_FOCUS;
+  if ( ui->fds == ui->touch_focus_fds )
+    ui->dflags |= MUIF_DFLAG_IS_TOUCH_FOCUS;
+  
+
+  /* get the id0 and id1 values */
+  if  ( ui->cmd == 'F' || ui->cmd == 'B' || ui->cmd == 'T' || ui->cmd == 'A' )
+  {
+      ui->id0 = mui_get_fds_char(ui->fds+1);
+      ui->id1 = mui_get_fds_char(ui->fds+2);
+      ui->x = mui_get_fds_char(ui->fds+3);
+      ui->y = mui_get_fds_char(ui->fds+4);
+      if ( ui->cmd == 'A' || ui->cmd == 'T' )
+      {
+        ui->arg = mui_get_fds_char(ui->fds+5);
+      }
+  }
+  else if ( ui->cmd == 'D' || ui->cmd == 'Z' )
+  {
+      ui->id0 = mui_get_fds_char(ui->fds+1);
+      ui->id1 = mui_get_fds_char(ui->fds+2);
+  }
+  else if ( ui->cmd == 'S' )
+  {
+      ui->id0 = 'S';
+      ui->id1 = mui_get_fds_char(ui->fds+1);
+  }
+  else
+  {
+      ui->id0 = '.';
+      /* note that ui->id1 contains the original cmd value */
+      ui->x = mui_get_fds_char(ui->fds+1);
+      ui->y = mui_get_fds_char(ui->fds+2);
+      if ( ui->cmd == 'G' || ui->cmd == 'M' )  /* this is also true for 'g' or 'm' */
+      {
+        ui->arg = mui_get_fds_char(ui->fds+3);
+      }
+  }
+
+  //MUI_DEBUG("mui_prepare_current_field cmd='%c' len=%d arg=%d\n", ui->cmd, ui->len, ui->arg);
+
+  
+  /* find the field  */
+  muif_tidx = mui_find_uif(ui, ui->id0, ui->id1);
+  //printf("mui_prepare_current_field: muif_tidx=%d\n", muif_tidx);
+  if ( muif_tidx >= 0 )
+  {
+    ui->uif = ui->muif_tlist + muif_tidx;
+    return 1;
+  }
+  return 0;
+}
+
+/* 
+  assumes that ui->fds has been assigned correctly 
+  and that ui->target_fds and ui->tmp_fds had been cleared if required
+
+  Usually do not call this function directly, instead use mui_loop_over_form
+
+*/
+
+static void mui_inner_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui)) MUI_NOINLINE;
+static void mui_inner_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui))
+{
+  uint8_t cmd;
+
+  //MUI_DEBUG("mui_inner_loop_over_form start %p\n", task);
+  
+  ui->fds += mui_fds_get_cmd_size(ui, ui->fds);      // skip the first entry, it is U always
+  for(;;)
+  {    
+    //printf("fds=%p *fds='%c'\n", ui->fds, ui->fds[0]);
+    /* get the command and check whether end of form is reached */
+    cmd = mui_get_fds_char(ui->fds);
+    if ( cmd == 'U' || cmd == 0 )
+      break;
+    if ( mui_prepare_current_field(ui) )  /* side effect: calculate ui->len */
+      if ( task(ui) )         /* call the task, which was provided as argument to this function */
+      {
+        //MUI_DEBUG("mui_inner_loop_over_form break by task\n");
+        break;
+      }
+    ui->fds += ui->len;
+  }
+  
+  //MUI_DEBUG("mui_inner_loop_over_form end %p\n", task);
+}
+
+static void mui_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui)) MUI_NOINLINE;
+static void mui_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui))
+{
+  if ( mui_IsFormActive(ui) == 0 )
+    return;
+  
+  ui->fds = ui->current_form_fds;
+  ui->target_fds = NULL;
+  ui->tmp_fds = NULL;
+  
+  mui_inner_loop_over_form(ui, task);  
+}
+
+/*
+  n is the form number
+*/
+fds_t *mui_find_form(mui_t *ui, uint8_t n)
+{
+  fds_t *fds = ui->root_fds;
+  uint8_t cmd;
+  
+  for( ;; )
+  {
+    cmd = mui_get_fds_char(fds);
+    if ( cmd == 0 )
+      break;
+    if ( cmd == 'U'  )
+    {
+      if (   mui_get_fds_char(fds+1) == n )
+      {
+        return fds;
+      }
+      /* not found, just coninue */
+    }
+    
+    fds += mui_fds_get_cmd_size(ui, fds);
+  }
+  return NULL;
+}
+
+/* === task procedures (arguments for mui_loop_over_form) === */
+/* ui->fds contains the current field */
+
+uint8_t mui_task_draw(mui_t *ui)
+{
+  //printf("mui_task_draw fds=%p uif=%p text=%s\n", ui->fds, ui->uif, ui->text);
+  muif_get_cb(ui->uif)(ui, MUIF_MSG_DRAW);
+  return 0;     /* continue with the loop */
+}
+
+uint8_t mui_task_form_start(mui_t *ui)
+{
+  muif_get_cb(ui->uif)(ui, MUIF_MSG_FORM_START);
+  return 0;     /* continue with the loop */
+}
+
+uint8_t mui_task_form_end(mui_t *ui)
+{
+  muif_get_cb(ui->uif)(ui, MUIF_MSG_FORM_END);
+  return 0;     /* continue with the loop */
+}
+
+static uint8_t mui_uif_is_cursor_selectable(mui_t *ui) MUI_NOINLINE;
+static uint8_t mui_uif_is_cursor_selectable(mui_t *ui)
+{
+  if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
+  {
+    return 1;
+  }
+  return 0;
+}
+
+uint8_t mui_task_find_prev_cursor_uif(mui_t *ui)
+{
+  //if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
+  if ( mui_uif_is_cursor_selectable(ui) )
+  {
+    if ( ui->fds == ui->cursor_focus_fds )
+    {
+      ui->target_fds = ui->tmp_fds;
+      return 1;         /* stop looping */
+    }
+    ui->tmp_fds = ui->fds;
+  }
+  return 0;     /* continue with the loop */
+}
+
+uint8_t mui_task_find_first_cursor_uif(mui_t *ui)
+{
+  //if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
+  if ( mui_uif_is_cursor_selectable(ui) )
+  {
+    // if ( ui->target_fds == NULL )
+    // {
+      ui->target_fds = ui->fds;
+      return 1;         /* stop looping */
+    // }
+  }
+  return 0;     /* continue with the loop */
+}
+
+uint8_t mui_task_find_last_cursor_uif(mui_t *ui)
+{
+  //if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
+  if ( mui_uif_is_cursor_selectable(ui) )
+  {
+    //ui->cursor_focus_position++;
+    ui->target_fds = ui->fds;
+  }
+  return 0;     /* continue with the loop */
+}
+
+uint8_t mui_task_find_next_cursor_uif(mui_t *ui)
+{
+  //if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
+  if ( mui_uif_is_cursor_selectable(ui) )
+  {
+    if ( ui->tmp_fds != NULL )
+    {
+      ui->target_fds = ui->fds;        
+      ui->tmp_fds = NULL;
+      return 1;         /* stop looping */
+    }
+    if ( ui->fds == ui->cursor_focus_fds )
+    {
+      ui->tmp_fds = ui->fds;
+    }
+  }
+  return 0;     /* continue with the loop */
+}
+
+uint8_t mui_task_get_current_cursor_focus_position(mui_t *ui)
+{
+  //if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
+  if ( mui_uif_is_cursor_selectable(ui) )
+  {
+    if ( ui->fds == ui->cursor_focus_fds )
+      return 1;         /* stop looping */
+    ui->tmp8++;
+  }
+  return 0;     /* continue with the loop */
+}
+
+uint8_t mui_task_read_nth_selectable_field(mui_t *ui)
+{
+  //if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_CURSOR_SELECTABLE )
+  if ( mui_uif_is_cursor_selectable(ui) )
+  {
+    if ( ui->tmp8 == 0 )
+      return 1;         /* stop looping */
+    ui->tmp8--;
+  }
+  return 0;     /* continue with the loop */
+}
+
+uint8_t mui_task_find_execute_on_select_field(mui_t *ui)
+{
+  if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_EXECUTE_ON_SELECT )
+  {
+      ui->target_fds = ui->fds;
+      return 1;         /* stop looping */
+  }
+  return 0;     /* continue with the loop */
+}
+
+
+/* === utility functions for the user API === */
+
+static uint8_t mui_send_cursor_msg(mui_t *ui, uint8_t msg) MUI_NOINLINE;
+static uint8_t mui_send_cursor_msg(mui_t *ui, uint8_t msg)
+{
+  if ( ui->cursor_focus_fds )
+  {
+    ui->fds = ui->cursor_focus_fds;
+    if ( mui_prepare_current_field(ui) )
+      return muif_get_cb(ui->uif)(ui, msg);
+  }
+  return 0; /* not called, msg not handled */
+}
+
+/* === user API === */
+
+/* 
+  returns the field pos which has the current focus 
+  If the first selectable field has the focus, then 0 will be returned
+  Unselectable fields (for example labels) are skipped by this count.
+  If no fields are selectable, then 0 is returned
+
+  The return value can be used as last argument for mui_EnterForm or mui_GotoForm
+
+  WARNING: This function will destroy current fds and field information.
+*/
+uint8_t mui_GetCurrentCursorFocusPosition(mui_t *ui)
+{
+  //fds_t *fds = ui->fds;
+  ui->tmp8 = 0;  
+  mui_loop_over_form(ui, mui_task_get_current_cursor_focus_position);
+  //ui->fds = fds;
+  return ui->tmp8;
+}
+
+
+void mui_Draw(mui_t *ui)
+{
+  mui_loop_over_form(ui, mui_task_draw);
+}
+
+void mui_next_field(mui_t *ui)
+{
+  mui_loop_over_form(ui, mui_task_find_next_cursor_uif);
+  // ui->cursor_focus_position++;
+  ui->cursor_focus_fds = ui->target_fds;      // NULL is ok  
+  if ( ui->target_fds == NULL )
+  {
+    mui_loop_over_form(ui, mui_task_find_first_cursor_uif);
+    ui->cursor_focus_fds = ui->target_fds;      // NULL is ok  
+    // ui->cursor_focus_position = 0;
+  }
+}
+
+
+/*
+  this function will overwrite the ui field related member variables
+  nth_token can be 0 if the fiel text is not a option list
+  the result is stored in ui->text
+  
+  token delimiter is '|' (pipe symbol)
+  
+  fds:  The start of a field (MUI_DATA)
+  nth_token: The position of the token, which should be returned
+*/
+uint8_t mui_GetSelectableFieldTextOption(mui_t *ui, fds_t *fds, uint8_t nth_token)
+{
+  fds_t *fds_backup = ui->fds;                                // backup the current fds, so that this function can be called inside a task loop 
+  int len = ui->len;          // backup length of the current command, 26 sep 2021: probably this is not required any more
+  uint8_t is_found;
+  
+  ui->fds = fds;
+  // at this point ui->fds contains the field which contains the tokens  
+  // now get the opion string out of the text field. nth_token can be 0 if this is no opion string
+  is_found = mui_fds_get_nth_token(ui, nth_token);          // return value is ignored here
+  
+  ui->fds = fds_backup;                        // restore the previous fds position
+  ui->len = len;
+  // result is stored in ui->text
+  return is_found;
+}
+
+uint8_t mui_GetSelectableFieldOptionCnt(mui_t *ui, fds_t *fds)
+{
+  fds_t *fds_backup = ui->fds;                                // backup the current fds, so that this function can be called inside a task loop 
+  int len = ui->len;          // backup length of the current command   26 sep 2021: probably this is not required any more
+  uint8_t cnt = 0;
+  
+  ui->fds = fds;
+  // at this point ui->fds contains the field which contains the tokens  
+  // now get the opion string out of the text field. nth_token can be 0 if this is no opion string
+  cnt = mui_fds_get_token_cnt(ui); 
+  
+  ui->fds = fds_backup;                        // restore the previous fds position
+  ui->len = len;
+  // result is stored in ui->text
+  return cnt;
+}
+
+
+
+//static void mui_send_cursor_enter_msg(mui_t *ui) MUI_NOINLINE;
+static uint8_t mui_send_cursor_enter_msg(mui_t *ui)
+{
+  ui->is_mud = 0;
+  return mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_ENTER);
+}
+
+/* 
+  if called from a field function, then the current field variables are destroyed, so that call should be the last call in the field callback.
+  mui_EnterForm is similar to mui_GotoForm and differes only in the second argument (which is the form id instead of the fds pointer)
+*/
+void mui_EnterForm(mui_t *ui, fds_t *fds, uint8_t initial_cursor_position)
+{
+  /* exit any previous form, will not do anything if there is no current form */
+  mui_LeaveForm(ui);
+  
+  /* clean focus fields */
+  ui->touch_focus_fds = NULL;
+  ui->cursor_focus_fds = NULL;
+  
+  /* reset all the scoll values */
+  ui->form_scroll_top = 0;
+  ui->form_scroll_visible = 0;
+  ui->form_scroll_total = 0;
+  
+  /* assign the form, which should be entered */
+  ui->current_form_fds = fds;
+  
+  /* inform all fields that we start a new form */
+  MUI_DEBUG("mui_EnterForm: form_start, initial_cursor_position=%d\n", initial_cursor_position);
+  mui_loop_over_form(ui, mui_task_form_start);
+  
+  /* assign initional cursor focus */
+  MUI_DEBUG("mui_EnterForm: find_first_cursor_uif\n");
+  mui_loop_over_form(ui, mui_task_find_first_cursor_uif);  
+  ui->cursor_focus_fds = ui->target_fds;      // NULL is ok  
+  MUI_DEBUG("mui_EnterForm: find_first_cursor_uif target_fds=%p\n", ui->target_fds);
+  
+  while( initial_cursor_position > 0 )
+  {
+    mui_NextField(ui);          // mui_next_field(ui) is not sufficient in case of scrolling
+    initial_cursor_position--;
+  }
+  
+  while( mui_send_cursor_enter_msg(ui) == 255 )
+  {
+    mui_NextField(ui);          // mui_next_field(ui) is not sufficient in case of scrolling
+  }
+}
+
+/* input: current_form_fds */
+/*
+  if called from a field function, then the current field variables are destroyed, so that call should be the last call in the field callback.
+*/
+void mui_LeaveForm(mui_t *ui)
+{
+  if ( mui_IsFormActive(ui) == 0 )
+    return;
+  
+  mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_LEAVE);
+  ui->cursor_focus_fds = NULL;
+  
+  /* inform all fields that we leave the form */
+  MUI_DEBUG("mui_LeaveForm: form_end\n");
+  mui_loop_over_form(ui, mui_task_form_end);  
+  ui->current_form_fds = NULL;
+}
+
+/* 0: error, form not found */
+/*
+  if called from a field function, then the current field variables are destroyed, so that call should be the last call in the field callback.
+*/
+uint8_t mui_GotoForm(mui_t *ui, uint8_t form_id, uint8_t initial_cursor_position)
+{
+  fds_t *fds = mui_find_form(ui, form_id);
+  if ( fds == NULL )
+    return 0;
+  /* EnterForm will also leave any previous form */
+  mui_EnterForm(ui, fds, initial_cursor_position);
+  return 1;
+}
+
+void mui_SaveForm(mui_t *ui)
+{
+  if ( mui_IsFormActive(ui) == 0 )
+    return;
+  
+  ui->last_form_fds = ui->cursor_focus_fds;
+  ui->last_form_id = mui_get_fds_char(ui->current_form_fds+1);
+  ui->last_form_cursor_focus_position = mui_GetCurrentCursorFocusPosition(ui);
+}
+
+/*
+  if called from a field function, then the current field variables are destroyed, so that call should be the last call in the field callback.
+*/
+void mui_RestoreForm(mui_t *ui)
+{
+  mui_GotoForm(ui, ui->last_form_id, ui->last_form_cursor_focus_position);
+}
+
+/*
+  Save a cursor position for mui_GotoFormAutoCursorPosition command
+  Two such positions is stored.
+*/
+void mui_SaveCursorPosition(mui_t *ui, uint8_t cursor_position)
+{
+  uint8_t form_id = mui_get_fds_char(ui->current_form_fds+1);
+  MUI_DEBUG("mui_SaveCursorPosition form_id=%d cursor_position=%d\n", form_id, cursor_position);
+  
+  if ( form_id == ui->menu_form_id[0] )
+    ui->menu_form_last_added = 0;
+  else if ( form_id == ui->menu_form_id[1] )
+    ui->menu_form_last_added = 1;
+  else 
+    ui->menu_form_last_added ^= 1;
+  ui->menu_form_id[ui->menu_form_last_added] = form_id;
+  ui->menu_form_cursor_focus_position[ui->menu_form_last_added] = cursor_position;
+  MUI_DEBUG("mui_SaveCursorPosition ui->menu_form_last_added=%d \n", ui->menu_form_last_added);
+}
+
+/*
+  Similar to mui_GotoForm, but will jump to previously stored cursor location (mui_SaveCursorPosition) or 0 if the cursor position was not saved.
+*/
+uint8_t mui_GotoFormAutoCursorPosition(mui_t *ui, uint8_t form_id)
+{
+  uint8_t cursor_position = 0;
+  if ( form_id == ui->menu_form_id[0] )
+    cursor_position = ui->menu_form_cursor_focus_position[0];
+  if ( form_id == ui->menu_form_id[1] )
+    cursor_position = ui->menu_form_cursor_focus_position[1];
+  MUI_DEBUG("mui_GotoFormAutoCursorPosition form_id=%d cursor_position=%d\n", form_id, cursor_position);
+  return mui_GotoForm(ui, form_id, cursor_position);
+}
+
+/*
+  return current form id or -1 if the menu system is inactive
+*/
+int mui_GetCurrentFormId(mui_t *ui)
+{
+  if ( mui_IsFormActive(ui) == 0 )
+    return -1;
+  return mui_get_fds_char(ui->current_form_fds+1);
+}
+
+/*
+  updates "ui->cursor_focus_fds"
+*/
+/*
+  if called from a field function, then the current field variables are destroyed, so that call should be the last call in the field callback.
+*/
+void mui_NextField(mui_t *ui)
+{
+  do 
+  {
+    if ( mui_send_cursor_msg(ui, MUIF_MSG_EVENT_NEXT) )
+      return;
+    mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_LEAVE);
+    mui_next_field(ui);
+  } while ( mui_send_cursor_enter_msg(ui) == 255 );
+}
+
+/*
+  updates "ui->cursor_focus_fds"
+*/
+/*
+  if called from a field function, then the current field variables are destroyed, so that call should be the last call in the field callback.
+*/
+void mui_PrevField(mui_t *ui)
+{
+  do
+  {
+    if ( mui_send_cursor_msg(ui, MUIF_MSG_EVENT_PREV) )
+      return;
+    mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_LEAVE);
+ 
+    mui_loop_over_form(ui, mui_task_find_prev_cursor_uif);
+    ui->cursor_focus_fds = ui->target_fds;      // NULL is ok  
+    if ( ui->target_fds == NULL )
+    {
+      //ui->cursor_focus_position = 0;
+      mui_loop_over_form(ui, mui_task_find_last_cursor_uif);
+      ui->cursor_focus_fds = ui->target_fds;      // NULL is ok  
+    }
+  } while( mui_send_cursor_enter_msg(ui) == 255 );
+}
+
+
+void mui_SendSelect(mui_t *ui)
+{
+  mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_SELECT);  
+}
+
+/*
+  Same as mui_SendSelect(), but will try to find a field, which is marked as "execute on select" (MUIF_EXECUTE_ON_SELECT_BUTTON).
+  If such a field exists, then this field is executed, otherwise the current field will receive the select message.
+
+  MUIF_EXECUTE_ON_SELECT_BUTTON is set by muif macro MUIF_EXECUTE_ON_SELECT_BUTTON
+  
+  used by MUIInputVersatileRotaryEncoder.ino example
+*/
+void mui_SendSelectWithExecuteOnSelectFieldSearch(mui_t *ui)
+{
+  mui_loop_over_form(ui, mui_task_find_execute_on_select_field);  /* Is there a exec on select field? */
+  if ( ui->target_fds != NULL )       /* yes, found, ui->fds already points to the field */
+  {
+    fds_t *exec_on_select_field = ui->target_fds;
+    mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_LEAVE);
+    ui->cursor_focus_fds = exec_on_select_field;    /* more cursor on the "exec on select" field */
+    mui_send_cursor_enter_msg(ui);      
+    mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_SELECT);  
+  }
+  else
+  {
+    /* no "exec on select" field found, just send the select message to the field */
+    mui_send_cursor_msg(ui, MUIF_MSG_CURSOR_SELECT);  
+  }
+}
+
+
+void mui_SendValueIncrement(mui_t *ui)
+{
+  mui_send_cursor_msg(ui, MUIF_MSG_VALUE_INCREMENT);  
+}
+
+void mui_SendValueDecrement(mui_t *ui)
+{
+  mui_send_cursor_msg(ui, MUIF_MSG_VALUE_DECREMENT);  
+}

+ 609 - 0
components/u8g2/mui.h

@@ -0,0 +1,609 @@
+/*
+
+  mui.h
+
+  Monochrome minimal user interface: Core library.
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2021, 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.  
+  
+  MUIF  (Monochrome User Interface Functions)
+    n:  A number 0 to 9 without any quotes, e.g.: 5
+    id: Exactly two characters or numbers in double quotes, e.g. "G5".
+    cb: A callback function with the following prototype: "uint8_t muif_cb(mui_t *ui, uint8_t msg)"
+      There are MANY predefined callback functions, see separate list
+    var: Address of a variable. 
+    text: Normal text, but special characters might be required for some callback functions, for
+      example the text might contain a list of selectable elements separated with the '|' symbol.
+
+  MUIF_STYLE(n,cb)
+    Corresponding FDS command: MUI_STYLE(n)
+    Change the style of any other elements after MUI_STYLE(n), does not draw anything
+    
+  MUIF_RO(id,cb)
+    Corresponding FDS command: MUI_DATA(id, text) MUI_XY(id, x, y), MUI_XYT(id, x,y,text), MUI_XYA(id, x,y,a), MUI_XYAT(id, x,y,a,text)
+    Places a read only element on the form. 
+    The correct FDS command depends on the callback function.
+    
+  MUIF_LABEL(cb)
+    Corresponding FDS command: MUI_LABEL(x,y,text)
+    Places a text at the specified position, similar to MUIF_RO
+    
+  MUIF_GOTO(cb)
+    Corresponding FDS command: MUI_GOTO(x,y,n,text)
+    Places a button at the specified position, similar to MUIF_BUTTON, but does not require an ID.
+    
+  MUIF_BUTTON(id,cb)
+    Corresponding FDS command: MUI_XY(id, x, y), MUI_XYT(id, x,y,text), MUI_XYA(id, x,y,a), MUI_XYAT(id, x,y,a,text)
+    Places a selectable element on the form. 
+  
+  MUIF_VARIABLE(id,var,cb)
+    Corresponding FDS command: MUI_XY(id, x, y), MUI_XYA(id, x,y,a)
+    Places a user input element at the specified location.
+    The correct FDS command depends on the callback function.
+
+
+*/
+
+#ifndef MUI_H
+#define MUI_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#if defined(__GNUC__) && defined(__AVR__)
+#include <avr/pgmspace.h>
+#endif 
+
+
+/*==========================================*/
+/* C++ compatible */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*==========================================*/
+/* defines */
+
+#define MUI_CHECK_EOFDS
+
+
+/*==========================================*/
+/* GNUC AVR PROGMEM interface */
+
+#ifdef __GNUC__
+#  define MUI_NOINLINE __attribute__((noinline))
+#else
+#  define MUI_NOINLINE
+#endif
+
+
+#if defined(__GNUC__) && defined(__AVR__)
+#  define mui_pgm_read(adr) pgm_read_byte_near(adr)
+#  define mui_pgm_wread(adr) pgm_read_word_near(adr) 
+#  define MUI_PROGMEM PROGMEM
+#endif
+
+
+#ifndef mui_pgm_read
+#  ifndef CHAR_BIT
+#  	define mui_pgm_read(adr) (*(const uint8_t *)(adr)) 
+#  else
+#	if CHAR_BIT > 8 
+#  	  define mui_pgm_read(adr) ((*(const uint8_t *)(adr)) & 0x0ff)
+#     else
+#  	  define mui_pgm_read(adr) (*(const uint8_t *)(adr)) 
+#     endif 
+#  endif
+#endif
+
+#ifndef mui_pgm_wread
+#  	define mui_pgm_wread(adr) (*(const uint16_t *)(adr)) 
+#endif
+
+#ifndef MUI_PROGMEM
+#  define MUI_PROGMEM
+#endif
+
+
+/*=== forward declarations ===*/
+typedef struct mui_struct mui_t;
+typedef const struct muif_struct muif_t;
+typedef uint8_t (*muif_cb)(mui_t *ui, uint8_t msg);
+typedef const char fds_t MUI_PROGMEM;
+
+
+
+/*=== struct declarations === */
+
+struct muif_struct
+{
+  uint8_t id0;
+  uint8_t id1;
+  uint8_t cflags;             // config flags e.g. MUIF_CFLAG_IS_CURSOR_SELECTABLE, if so, then it will not receive any cursor/touch msgs
+  uint8_t extra;
+  void *data;                           // might be a pointer to a variable
+  muif_cb cb;                        // callback
+} MUI_PROGMEM;
+
+/* assumes that pointers are 16 bit so encapsulate the wread i another ifdef __AVR__ */
+#if defined(__GNUC__) && defined(__AVR__)
+#  define muif_get_id0(muif) mui_pgm_read(&((muif)->id0))
+#  define muif_get_id1(muif) mui_pgm_read(&((muif)->id1))
+#  define muif_get_cflags(muif) mui_pgm_read(&((muif)->cflags))
+#  define muif_get_extra(muif) mui_pgm_read(&((muif)->extra))
+#  define muif_get_data(muif) ((void *)mui_pgm_wread(&((muif)->data)))
+#  define muif_get_cb(muif) ((muif_cb)mui_pgm_wread(&((muif)->cb)))
+#else
+#  define muif_get_id0(muif) ((muif)->id0)
+#  define muif_get_id1(muif) ((muif)->id1)
+#  define muif_get_cflags(muif) ((muif)->cflags)
+#  define muif_get_extra(muif) ((muif)->extra)
+#  define muif_get_data(muif) ((muif)->data)
+#  define muif_get_cb(muif) ((muif)->cb)
+#endif
+
+
+
+#define MUIF_MSG_NONE 0
+#define MUIF_MSG_DRAW 1
+#define MUIF_MSG_FORM_START 2
+#define MUIF_MSG_FORM_END 3
+/* MUIF_MSG_CURSOR_ENTER return values: 255=skip this field, <255, continue*/
+#define MUIF_MSG_CURSOR_ENTER 4
+#define MUIF_MSG_CURSOR_SELECT 5
+
+/* optional VALUE messages, ignored by the mui core, but can be used inside the field functions  */
+/* usually MUIF_MSG_VALUE_INCREMENT behaves like  MUIF_MSG_CURSOR_SELECT */
+#define MUIF_MSG_VALUE_INCREMENT 6
+#define MUIF_MSG_VALUE_DECREMENT 7
+
+
+#define MUIF_MSG_CURSOR_LEAVE 8
+#define MUIF_MSG_TOUCH_DOWN 9
+#define MUIF_MSG_TOUCH_UP 10
+/* MUIF_MSG_EVENT_NEXT return values: 0=not handled, 1=handled, do nothing */
+/* If MUIF_MSG_EVENT_NEXT/PREV are NOT handled by the field function, then this msg will change the field */
+#define MUIF_MSG_EVENT_NEXT 11
+/* MUIF_MSG_EVENT_PREV return values: 0=not handled, 1=handled, do nothing */
+#define MUIF_MSG_EVENT_PREV 12
+
+/* dynamic flags */
+#define MUIF_DFLAG_IS_CURSOR_FOCUS 0x01
+#define MUIF_DFLAG_IS_TOUCH_FOCUS 0x02
+  
+/* config flags */
+#define MUIF_CFLAG_IS_CURSOR_SELECTABLE 0x01
+#define MUIF_CFLAG_IS_TOUCH_SELECTABLE 0x02
+#define MUIF_CFLAG_IS_EXECUTE_ON_SELECT 0x04
+
+
+/* end user MUIF entries */
+#define MUIF(id,cflags,data,cb) { id[0], id[1], cflags, 0, data, cb} 
+#define MUIF_STYLE(n,cb)  MUIF("S" #n, 0, 0, cb) 
+#define MUIF_RO(id,cb) MUIF(id,0, 0,cb)
+#define MUIF_LABEL(cb) MUIF(".L",0, 0,cb)
+#define MUIF_GOTO(cb) MUIF(".G",MUIF_CFLAG_IS_CURSOR_SELECTABLE,0,cb)
+#define MUIF_BUTTON(id,cb) MUIF(id,MUIF_CFLAG_IS_CURSOR_SELECTABLE,0,cb)
+#define MUIF_EXECUTE_ON_SELECT_BUTTON(id,cb) MUIF(id,MUIF_CFLAG_IS_CURSOR_SELECTABLE|MUIF_CFLAG_IS_EXECUTE_ON_SELECT,0,cb)
+#define MUIF_VARIABLE(id,var,cb) MUIF(id,MUIF_CFLAG_IS_CURSOR_SELECTABLE,(var),cb)
+
+
+
+/* must be smaller than or equal to 255 */
+#ifndef MUI_MAX_TEXT_LEN
+#define MUI_MAX_TEXT_LEN 41
+#endif
+
+#define MUI_MENU_CACHE_CNT 2
+
+struct mui_struct
+{
+  void *graphics_data;
+  fds_t *root_fds;  
+  
+  muif_t *muif_tlist;
+  size_t muif_tcnt;
+  
+  fds_t *current_form_fds;         // the current form, NULL if the ui is not active at the moment
+  fds_t *cursor_focus_fds;           // the field which has the current cursor focus, NULL if there is no current focus
+  fds_t *touch_focus_fds;            // the field which has touch focus
+
+  fds_t *token;             // current token position
+
+  uint16_t form_scroll_total;            // reserved for MUIF, not used by mui
+  uint16_t form_scroll_top;              // reserved for MUIF, not used by mui
+  uint8_t form_scroll_visible;          // reserved for MUIF, not used by mui
+  
+  
+  //uint8_t selected_value;   // This variable is not used by the user interface but can be used by any field function
+  uint8_t tmp8;
+  
+  /* 0: mse, 1: mud */
+  uint8_t is_mud;         // a temp variable for the MUIF function to store remember up down mode. This variable will be cleared before sending MUIF_MSG_CURSOR_ENTER
+  /* current field/style variables */
+  //uint8_t cursor_focus_position;        // the index of the field which has focus, can be used as last argument for mui_EnterForm
+  
+  uint8_t delimiter;    // outer delimiter of the text part of a field
+  uint8_t cmd;          // current cmd or field (e.g. U or F)
+  uint8_t id0;            // identifier of the field, manually provided or derived (G cmd has fixed id "FG")
+  uint8_t id1;
+  uint8_t x;               // position of the field
+  uint8_t y;
+  uint8_t dflags;
+  uint8_t arg;          // extra argument of the field. For example the G: form is put here
+  int len;          // length of the current command
+  fds_t *fds;             // current position, *fds = cmd
+  muif_t *uif;                   // user interface field or style for the given id0 / id1, assigned by mui_prepare_current_field()
+  char text[MUI_MAX_TEXT_LEN+1];
+
+  /* target  */
+  fds_t *tmp_fds;
+  fds_t *target_fds;     // used by several task functions as a return / result value
+  
+  /* last form and field, used by mui_SaveForm and mui_RestoreForm */
+  uint8_t last_form_id;
+  uint8_t last_form_cursor_focus_position;
+  fds_t *last_form_fds;           // not used by mui_RestoreForm, but can be used by field functions
+  
+  /* menu cursor position backup */
+  uint8_t menu_form_id[MUI_MENU_CACHE_CNT];
+  uint8_t menu_form_cursor_focus_position[MUI_MENU_CACHE_CNT];
+  uint8_t menu_form_last_added;
+} ;
+
+#define mui_IsCursorFocus(mui) ((mui)->dflags & MUIF_DFLAG_IS_CURSOR_FOCUS)
+#define mui_IsTouchFocus(mui) ((mui)->dflags & MUIF_CFLAG_IS_TOUCH_SELECTABLE)
+
+
+
+
+/*=== form string definitions ===*/
+
+#define MUI_0 "\x00"
+#define MUI_1 "\x01"
+#define MUI_2 "\x02"
+#define MUI_3 "\x03"
+#define MUI_4 "\x04"
+#define MUI_5 "\x05"
+#define MUI_6 "\x06"
+#define MUI_7 "\x07"
+#define MUI_8 "\x08"
+#define MUI_9 "\x09"
+#define MUI_10 "\x0a"
+#define MUI_11 "\x0b"
+#define MUI_12 "\x0c"
+#define MUI_13 "\x0d"
+#define MUI_14 "\x0e"
+#define MUI_15 "\x0f"
+#define MUI_16 "\x10"
+#define MUI_17 "\x11"
+#define MUI_18 "\x12"
+#define MUI_19 "\x13"
+#define MUI_20 "\x14"
+#define MUI_21 "\x15"
+#define MUI_22 "\x16"
+#define MUI_23 "\x17"
+#define MUI_24 "\x18"
+#define MUI_25 "\x19"
+#define MUI_26 "\x1a"
+#define MUI_27 "\x1b"
+#define MUI_28 "\x1c"
+#define MUI_29 "\x1d"
+#define MUI_30 "\x1e"
+#define MUI_31 "\x1f"
+#define MUI_32 "\x20"
+#define MUI_33 "\x21"
+#define MUI_34 "\x22"
+#define MUI_35 "\x23"
+#define MUI_36 "\x24"
+#define MUI_37 "\x25"
+#define MUI_38 "\x26"
+#define MUI_39 "\x27"
+#define MUI_40 "\x28"
+#define MUI_41 "\x29"
+#define MUI_42 "\x2a"
+#define MUI_43 "\x2b"
+#define MUI_44 "\x2c"
+#define MUI_45 "\x2d"
+#define MUI_46 "\x2e"
+#define MUI_47 "\x2f"
+#define MUI_48 "\x30"
+#define MUI_49 "\x31"
+#define MUI_50 "\x32"
+#define MUI_51 "\x33"
+#define MUI_52 "\x34"
+#define MUI_53 "\x35"
+#define MUI_54 "\x36"
+#define MUI_55 "\x37"
+#define MUI_56 "\x38"
+#define MUI_57 "\x39"
+#define MUI_58 "\x3a"
+#define MUI_59 "\x3b"
+#define MUI_60 "\x3c"
+#define MUI_61 "\x3d"
+#define MUI_62 "\x3e"
+#define MUI_63 "\x3f"
+#define MUI_64 "\x40"
+#define MUI_65 "\x41"
+#define MUI_66 "\x42"
+#define MUI_67 "\x43"
+#define MUI_68 "\x44"
+#define MUI_69 "\x45"
+#define MUI_70 "\x46"
+#define MUI_71 "\x47"
+#define MUI_72 "\x48"
+#define MUI_73 "\x49"
+#define MUI_74 "\x4a"
+#define MUI_75 "\x4b"
+#define MUI_76 "\x4c"
+#define MUI_77 "\x4d"
+#define MUI_78 "\x4e"
+#define MUI_79 "\x4f"
+#define MUI_80 "\x50"
+#define MUI_81 "\x51"
+#define MUI_82 "\x52"
+#define MUI_83 "\x53"
+#define MUI_84 "\x54"
+#define MUI_85 "\x55"
+#define MUI_86 "\x56"
+#define MUI_87 "\x57"
+#define MUI_88 "\x58"
+#define MUI_89 "\x59"
+#define MUI_90 "\x5a"
+#define MUI_91 "\x5b"
+#define MUI_92 "\x5c"
+#define MUI_93 "\x5d"
+#define MUI_94 "\x5e"
+#define MUI_95 "\x5f"
+#define MUI_96 "\x60"
+#define MUI_97 "\x61"
+#define MUI_98 "\x62"
+#define MUI_99 "\x63"
+#define MUI_100 "\x64"
+#define MUI_101 "\x65"
+#define MUI_102 "\x66"
+#define MUI_103 "\x67"
+#define MUI_104 "\x68"
+#define MUI_105 "\x69"
+#define MUI_106 "\x6a"
+#define MUI_107 "\x6b"
+#define MUI_108 "\x6c"
+#define MUI_109 "\x6d"
+#define MUI_110 "\x6e"
+#define MUI_111 "\x6f"
+#define MUI_112 "\x70"
+#define MUI_113 "\x71"
+#define MUI_114 "\x72"
+#define MUI_115 "\x73"
+#define MUI_116 "\x74"
+#define MUI_117 "\x75"
+#define MUI_118 "\x76"
+#define MUI_119 "\x77"
+#define MUI_120 "\x78"
+#define MUI_121 "\x79"
+#define MUI_122 "\x7a"
+#define MUI_123 "\x7b"
+#define MUI_124 "\x7c"
+#define MUI_125 "\x7d"
+#define MUI_126 "\x7e"
+#define MUI_127 "\x7f"
+#define MUI_128 "\x80"
+#define MUI_129 "\x81"
+#define MUI_130 "\x82"
+#define MUI_131 "\x83"
+#define MUI_132 "\x84"
+#define MUI_133 "\x85"
+#define MUI_134 "\x86"
+#define MUI_135 "\x87"
+#define MUI_136 "\x88"
+#define MUI_137 "\x89"
+#define MUI_138 "\x8a"
+#define MUI_139 "\x8b"
+#define MUI_140 "\x8c"
+#define MUI_141 "\x8d"
+#define MUI_142 "\x8e"
+#define MUI_143 "\x8f"
+#define MUI_144 "\x90"
+#define MUI_145 "\x91"
+#define MUI_146 "\x92"
+#define MUI_147 "\x93"
+#define MUI_148 "\x94"
+#define MUI_149 "\x95"
+#define MUI_150 "\x96"
+#define MUI_151 "\x97"
+#define MUI_152 "\x98"
+#define MUI_153 "\x99"
+#define MUI_154 "\x9a"
+#define MUI_155 "\x9b"
+#define MUI_156 "\x9c"
+#define MUI_157 "\x9d"
+#define MUI_158 "\x9e"
+#define MUI_159 "\x9f"
+#define MUI_160 "\xa0"
+#define MUI_161 "\xa1"
+#define MUI_162 "\xa2"
+#define MUI_163 "\xa3"
+#define MUI_164 "\xa4"
+#define MUI_165 "\xa5"
+#define MUI_166 "\xa6"
+#define MUI_167 "\xa7"
+#define MUI_168 "\xa8"
+#define MUI_169 "\xa9"
+#define MUI_170 "\xaa"
+#define MUI_171 "\xab"
+#define MUI_172 "\xac"
+#define MUI_173 "\xad"
+#define MUI_174 "\xae"
+#define MUI_175 "\xaf"
+#define MUI_176 "\xb0"
+#define MUI_177 "\xb1"
+#define MUI_178 "\xb2"
+#define MUI_179 "\xb3"
+#define MUI_180 "\xb4"
+#define MUI_181 "\xb5"
+#define MUI_182 "\xb6"
+#define MUI_183 "\xb7"
+#define MUI_184 "\xb8"
+#define MUI_185 "\xb9"
+#define MUI_186 "\xba"
+#define MUI_187 "\xbb"
+#define MUI_188 "\xbc"
+#define MUI_189 "\xbd"
+#define MUI_190 "\xbe"
+#define MUI_191 "\xbf"
+#define MUI_192 "\xc0"
+#define MUI_193 "\xc1"
+#define MUI_194 "\xc2"
+#define MUI_195 "\xc3"
+#define MUI_196 "\xc4"
+#define MUI_197 "\xc5"
+#define MUI_198 "\xc6"
+#define MUI_199 "\xc7"
+#define MUI_200 "\xc8"
+#define MUI_201 "\xc9"
+#define MUI_202 "\xca"
+#define MUI_203 "\xcb"
+#define MUI_204 "\xcc"
+#define MUI_205 "\xcd"
+#define MUI_206 "\xce"
+#define MUI_207 "\xcf"
+#define MUI_208 "\xd0"
+#define MUI_209 "\xd1"
+#define MUI_210 "\xd2"
+#define MUI_211 "\xd3"
+#define MUI_212 "\xd4"
+#define MUI_213 "\xd5"
+#define MUI_214 "\xd6"
+#define MUI_215 "\xd7"
+#define MUI_216 "\xd8"
+#define MUI_217 "\xd9"
+#define MUI_218 "\xda"
+#define MUI_219 "\xdb"
+#define MUI_220 "\xdc"
+#define MUI_221 "\xdd"
+#define MUI_222 "\xde"
+#define MUI_223 "\xdf"
+#define MUI_224 "\xe0"
+#define MUI_225 "\xe1"
+#define MUI_226 "\xe2"
+#define MUI_227 "\xe3"
+#define MUI_228 "\xe4"
+#define MUI_229 "\xe5"
+#define MUI_230 "\xe6"
+#define MUI_231 "\xe7"
+#define MUI_232 "\xe8"
+#define MUI_233 "\xe9"
+#define MUI_234 "\xea"
+#define MUI_235 "\xeb"
+#define MUI_236 "\xec"
+#define MUI_237 "\xed"
+#define MUI_238 "\xee"
+#define MUI_239 "\xef"
+#define MUI_240 "\xf0"
+#define MUI_241 "\xf1"
+#define MUI_242 "\xf2"
+#define MUI_243 "\xf3"
+#define MUI_244 "\xf4"
+#define MUI_245 "\xf5"
+#define MUI_246 "\xf6"
+#define MUI_247 "\xf7"
+#define MUI_248 "\xf8"
+#define MUI_249 "\xf9"
+#define MUI_250 "\xfa"
+#define MUI_251 "\xfb"
+#define MUI_252 "\xfc"
+#define MUI_253 "\xfd"
+#define MUI_254 "\xfe"
+#define MUI_255 "\xff"
+
+/* form: one id only */
+#define MUI_FORM(n) "U" MUI_##n
+
+/* style: one id only */
+#define MUI_STYLE(n) "S" #n
+
+#define MUI_AUX(id) "Z" id
+
+#define MUI_DATA(id, text) "D" id "\xff" text "\xff"
+
+#define MUI_XY(id, x, y) "F" id MUI_##x MUI_##y
+/* button id must be two chars, but must be unique everywhere */
+#define MUI_XYT(id, x,y,text) "B" id MUI_##x MUI_##y  "\xff" text "\xff"
+#define MUI_XYA(id, x,y,a) "A" id MUI_##x MUI_##y  MUI_##a
+#define MUI_XYAT(id, x,y,a,text) "T" id MUI_##x MUI_##y  MUI_##a "\xff" text "\xff"
+
+#define MUI_LABEL(x,y,text) "L" MUI_##x MUI_##y "\xff" text "\xff"
+#define MUI_GOTO(x,y,n,text) "G" MUI_##x MUI_##y MUI_##n "\xff" text "\xff"
+#define MUI_goto(x,y,n,text) "g" MUI_##x MUI_##y MUI_##n "\xff" text "\xff"
+
+
+uint8_t mui_get_fds_char(fds_t *s) MUI_NOINLINE;
+
+uint8_t mui_fds_first_token(mui_t *ui) MUI_NOINLINE;
+uint8_t mui_fds_next_token(mui_t *ui) MUI_NOINLINE;
+uint8_t mui_fds_get_nth_token(mui_t *ui, uint8_t n) MUI_NOINLINE;
+uint8_t mui_fds_get_token_cnt(mui_t *ui) MUI_NOINLINE;
+
+void mui_Init(mui_t *ui, void *graphics_data, fds_t *fds, muif_t *muif_tlist, size_t muif_tcnt);
+uint8_t mui_GetCurrentCursorFocusPosition(mui_t *ui) ;
+void mui_Draw(mui_t *ui);
+/* warning: The next function will overwrite the ui field variables like ui->arg, etc. 26 sep 2021: only ui->text is modified */
+uint8_t mui_GetSelectableFieldTextOption(mui_t *ui, fds_t *fds, uint8_t nth_token);
+/* warning: The next function will overwrite the ui field variables like ui->arg, etc 26 sep 2021: only ui->text is modified*/
+uint8_t mui_GetSelectableFieldOptionCnt(mui_t *ui, fds_t *fds);
+void mui_EnterForm(mui_t *ui, fds_t *fds, uint8_t initial_cursor_position);
+void mui_LeaveForm(mui_t *ui);
+uint8_t mui_GotoForm(mui_t *ui, uint8_t form_id, uint8_t initial_cursor_position);
+void mui_SaveForm(mui_t *ui);     /* Save current form+cursor position. Used together with mui_RestoreForm */
+void mui_RestoreForm(mui_t *ui);        /* Restore form and cursor position, previously saved with mui_SaveForm */
+void mui_SaveCursorPosition(mui_t *ui, uint8_t cursor_position);         /* stores a cursor position for use with mui_GotoFormAutoCursorPosition */
+uint8_t mui_GotoFormAutoCursorPosition(mui_t *ui, uint8_t form_id);
+
+int mui_GetCurrentFormId(mui_t *ui);    /* form id or -1 if the menu system is inactive */
+void mui_NextField(mui_t *ui);
+void mui_PrevField(mui_t *ui);
+void mui_SendSelect(mui_t *ui);
+void mui_SendSelectWithExecuteOnSelectFieldSearch(mui_t *ui);  /* use this if MUIF_EXECUTE_ON_SELECT_BUTTON is used */
+
+void mui_SendValueIncrement(mui_t *ui);
+void mui_SendValueDecrement(mui_t *ui);
+
+
+
+#define mui_IsFormActive(ui) ((ui)->current_form_fds != NULL) 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MUI_H */
+

+ 2243 - 0
components/u8g2/mui_u8g2.c

@@ -0,0 +1,2243 @@
+/*
+
+  mui_u8g2.c
+
+  Monochrome minimal user interface: Glue code between mui and u8g2.
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2021, 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.  
+
+*/
+
+/*
+
+  field function naming convention
+
+    action
+      draw_text:                        (rename from draw label)
+      draw_str:                      
+      btn_jmp   button jump to:                      a button which jumps to a specific form
+      btn_exit          button leave:                     a button which leaves the form and places an exit code into a uint8 variable
+      u8_value_0_9      
+      u8_chkbox
+      u8_radio
+      u8_opt_line       edit value options in the same line
+      u8_opt_parent       edit value options parent
+      u8_opt_child       edit value options child
+    
+    
+    field width (not for draw text/str)
+      wm                minimum width
+      wa                width can be provided via FDS argument
+      w1                full display width
+      w2                half display size (minus some pixel)
+      w3                one/third of the dispay width (minus some pixel)
+
+    edit mode  (not for draw text/str, buttons and checkbox)                  
+      mse       select: select event will increment the value or activate the field (buttons)
+      mud      up/down:  select will enter the up/down edit mode. Next/prev event will increment/decrement the value
+      
+    styles (not for draw text/str)
+      unselected                selected                        up/down edit                            postfix         Use for
+      plain                          invers                             invers + gap + frame            pi                      input elements
+      frame                         invers+frame                frame                                       fi                  buttons
+      
+      plain                          frame                              invers + frame                         pf               input elements
+      invers                        frame                               invers + frame                          if              buttons
+      
+      
+    mui_u8g2_[action]_[field_width]_[edit_mode]_[style]
+
+  mui _label_u8g2 --> mui_u8g2_draw_text
+  mui _goto_frame_button_invers_select_u8g2                              --> mui_u8g2_btn_goto_wm_fi
+  mui _goto_half_width_frame_button_invers_select_u8g2           --> mui_u8g2_btn_goto_w2_fi
+  mui _goto_line_button_invers_select_u8g2 -->  mui_u8g2_btn_goto_w1_fi
+  mui _leave_menu_frame_button_invers_select_u8g2 --> mui_u8g2_btn_exit_wm_fi
+  
+  mui _input_uint8_invers_select_u8g2 --> mui_u8g2_u8_value_0_9_wm_mse_pi
+  mui _single_line_option_invers_select_u8g2     --> mui_u8g2_u8_opt_line_wa_mse_pi
+  mui _select_options_parent_invers_select_u8g2  --> mui_u8g2_u8_opt_parent_wa_mse_pi
+  mui _select_options_child_invers_select_u8g2  --> mui_u8g2_u8_opt_child_wm_pi
+
+  mui _checkbox_invers_select_u8g2 --> mui_u8g2_u8_chkbox_wm_pi
+  mui _radio_invers_select_u8g2 --> mui_u8g2_u8_radio_wm_pi
+
+  mui _input_char_invers_select_u8g2 --> mui_u8g2_u8_char_wm_mud_pi
+
+
+
+  2 Buttons
+    Only use "mse", don't use "mud"
+  
+    Button      Call                            Description
+    1                mui_SendSelect()    Activate elements & change values
+    2                mui_NextField()      Goto next field
+    
+  3 Buttons
+    Use "mse" or "mud"
+    Button      Call                            Description
+    1                mui_SendSelect()    Activate elements / change values (mse) / enter "mud" mode (mud)
+    2                mui_NextField()      Goto next field, increment value (mud)
+    3                mui_PrevField()      Goto prev field, decrement value (mud)
+    
+  4 Buttons
+    Prefer "mse"
+    Button      Call                                            Description
+    1                mui_SendValueIncrement()    Activate elements / increment values (mse)
+    2                mui_SendValueDecrement()   Activate elements / decrement values (mse)
+    3                mui_NextField()                       Goto next field
+    4                mui_PrevField()                        Goto prev field
+
+  5 Buttons
+    Prefer "mse", use the MUIF_EXECUTE_ON_SELECT_BUTTON on forms to finish the form with the "form select" button 5
+    Button      Call                                                                                            Description
+    1                mui_SendValueIncrement()                                                           Activate elements / increment values (mse)
+    2                mui_SendValueDecrement()                                                         Activate elements / decrement values (mse)
+    3                mui_NextField()                                                                            Goto next field
+    4                mui_PrevField()                                                                     Goto prev field
+    5                mui_SendSelectWithExecuteOnSelectFieldSearch()             Execute the MUIF_EXECUTE_ON_SELECT_BUTTON button or activate the current element if there is no EOS button
+    
+  rotary encoder, push&release
+    Prefer "mud"
+    Button      Call                            Description
+    encoder button                 mui_SendSelect()    Activate elements / change values (mse) / enter "mud" mode (mud)
+    encoder CW                      mui_NextField()      Goto next field, increment value (mud)
+    encoder CCW                    mui_PrevField()      Goto prev field, decrement value (mud)
+  
+  rotary encoder, push&rotate
+    Prefer "mse"
+    Button                                      Call                                            Description
+    encoder CW                                  mui_SendValueIncrement()    Activate elements / increment values (mse)
+    encoder CCW                                 mui_SendValueDecrement()   Activate elements / decrement values (mse)
+    encoder CW+button press                mui_NextField()                       Goto next field
+    encoder CCW+button press                mui_PrevField()                        Goto prev field
+
+
+*/
+
+
+
+#include "mui.h"
+#include "u8g2.h"
+#include "mui_u8g2.h"
+
+/*
+
+uint8_t mui_template(mui_t *ui, uint8_t msg)
+{
+  //u8g2_t *u8g2 = mui_get_U8g2(ui);
+  //ui->dflags                          MUIF_DFLAG_IS_CURSOR_FOCUS       MUIF_DFLAG_IS_TOUCH_FOCUS
+  //muif_get_cflags(ui->uif)       MUIF_CFLAG_IS_CURSOR_SELECTABLE
+  //muif_get_data(ui->uif)
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_VALUE_INCREMENT:
+      break;
+    case MUIF_MSG_VALUE_DECREMENT:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+*/
+
+/*=========================================================================*/
+#define MUI_U8G2_V_PADDING 1
+
+/*=========================================================================*/
+/* extra u8g2 drawing functions */
+
+static void u8g2_DrawCheckbox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t is_checked) MUI_NOINLINE;
+static void u8g2_DrawCheckbox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t is_checked)
+{
+  u8g2_DrawFrame(u8g2, x, y-w, w, w);
+  if ( is_checked )
+  {
+    w-=4;
+    u8g2_DrawBox(u8g2, x+2, y-w-2, w, w);
+  }
+}
+
+static void u8g2_DrawValueMark(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w)
+{
+  u8g2_DrawBox(u8g2, x, y-w, w, w);
+}
+
+
+/*=========================================================================*/
+/* helper function */
+
+u8g2_uint_t mui_get_x(mui_t *ui) MUI_NOINLINE;
+u8g2_uint_t mui_get_x(mui_t *ui)
+{
+  if ( u8g2_GetDisplayWidth(mui_get_U8g2(ui)) >= 255 )
+      return ui->x * 2;
+  return ui->x;
+}
+
+u8g2_uint_t mui_get_y(mui_t *ui)
+{
+  return ui->y;
+}
+
+u8g2_t *mui_get_U8g2(mui_t *ui)
+{
+  return (u8g2_t *)(ui->graphics_data);
+}
+
+//void u8g2_DrawButtonUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t flags, u8g2_uint_t width, u8g2_uint_t padding_h, u8g2_uint_t padding_v, const char *text);
+void mui_u8g2_draw_button_utf(mui_t *ui, u8g2_uint_t flags, u8g2_uint_t width, u8g2_uint_t padding_h, u8g2_uint_t padding_v, const char *text)
+{
+  if ( text==NULL)
+    text = "";
+  u8g2_DrawButtonUTF8(mui_get_U8g2(ui), mui_get_x(ui), mui_get_y(ui), flags, width, padding_h, padding_v, text);
+}
+
+u8g2_uint_t mui_u8g2_get_pi_flags(mui_t *ui)
+{
+  u8g2_uint_t flags = 0;
+  if ( mui_IsCursorFocus(ui) )
+  {
+    flags |= U8G2_BTN_INV;
+    if ( ui->is_mud )
+    {
+      flags |= U8G2_BTN_XFRAME;
+    }      
+  }
+  return flags;
+}
+
+
+void mui_u8g2_draw_button_pi(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text)
+{
+  mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), width, padding_h , MUI_U8G2_V_PADDING, text);
+}
+
+
+u8g2_uint_t mui_u8g2_get_fi_flags(mui_t *ui)
+{
+  u8g2_uint_t flags = 1;
+  if ( mui_IsCursorFocus(ui) )
+  {
+    flags |= U8G2_BTN_INV;
+    if ( ui->is_mud )
+    {
+      flags = 1;        // undo INV
+    }      
+  }
+  return flags;
+}
+
+void mui_u8g2_draw_button_fi(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text)
+{
+  mui_u8g2_draw_button_utf(ui, mui_u8g2_get_fi_flags(ui), width, padding_h , MUI_U8G2_V_PADDING, text);
+}
+
+
+u8g2_uint_t mui_u8g2_get_pf_flags(mui_t *ui)
+{
+  u8g2_uint_t flags = 0;
+  if ( mui_IsCursorFocus(ui) )
+  {
+    flags |= 1;
+    if ( ui->is_mud )
+    {
+      flags |= U8G2_BTN_INV;
+    }      
+  }
+  return flags;
+}
+
+void mui_u8g2_draw_button_pf(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text)
+{
+  mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pf_flags(ui), width, padding_h , MUI_U8G2_V_PADDING, text);
+}
+
+
+u8g2_uint_t mui_u8g2_get_if_flags(mui_t *ui)
+{
+  u8g2_uint_t flags = 0;
+  if ( mui_IsCursorFocus(ui) )
+  {
+    if ( ui->is_mud )
+    {
+      flags |= 1;
+      flags |= U8G2_BTN_INV;
+    }
+    else
+    {
+      flags |= 1;
+    }
+  }
+  else
+  {
+      flags |= U8G2_BTN_INV;
+  }
+  return flags;
+}
+
+void mui_u8g2_draw_button_if(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text)
+{
+  mui_u8g2_draw_button_utf(ui, mui_u8g2_get_if_flags(ui), width, padding_h , MUI_U8G2_V_PADDING, text);
+}
+
+
+static uint8_t mui_u8g2_handle_scroll_next_prev_events(mui_t *ui, uint8_t msg) MUI_NOINLINE;
+static uint8_t mui_u8g2_handle_scroll_next_prev_events(mui_t *ui, uint8_t msg)
+{
+  uint8_t arg = ui->arg;
+  switch(msg)
+  {
+    case MUIF_MSG_CURSOR_ENTER:
+      if ( (arg > 0) && (ui->form_scroll_top + arg >= ui->form_scroll_total) )
+        return 255;
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      if ( arg+1 == ui->form_scroll_visible )
+      {
+        if ( ui->form_scroll_visible + ui->form_scroll_top < ui->form_scroll_total )
+        {
+          ui->form_scroll_top++;
+          return 1;
+        }
+        else
+        {
+          ui->form_scroll_top = 0;
+        }
+      }
+      break;
+    case MUIF_MSG_EVENT_PREV:
+      if ( arg == 0 )
+      {
+        if ( ui->form_scroll_top > 0 )
+        {
+          ui->form_scroll_top--;
+          return 1;
+        }
+        else
+        {
+          if ( ui->form_scroll_total >  ui->form_scroll_visible  )
+          {
+            ui->form_scroll_top = ui->form_scroll_total - ui->form_scroll_visible;
+          }
+          else
+          {
+            ui->form_scroll_top = 0;
+          }
+        }
+      }
+      break;
+  }
+  return 0;
+}
+
+/*=========================================================================*/
+/* simplified style function  */
+
+/*
+Used for MUIF_U8G2_FONT_STYLE(n,font)
+*/
+
+uint8_t mui_u8g2_set_font_style_function(mui_t *ui, uint8_t msg)
+{  
+  if ( msg == MUIF_MSG_DRAW )
+  {
+    u8g2_SetFont(mui_get_U8g2(ui), (uint8_t *)muif_get_data(ui->uif));
+  }
+  return 0;
+}
+
+
+
+/*=========================================================================*/
+/* field functions */
+
+/*
+  xy: yes, arg: no, text: yes
+*/
+
+uint8_t mui_u8g2_draw_text(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      u8g2_DrawUTF8(mui_get_U8g2(ui), mui_get_x(ui), mui_get_y(ui), ui->text);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+      break;
+    case MUIF_MSG_VALUE_INCREMENT:
+      break;
+    case MUIF_MSG_VALUE_DECREMENT:
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;    
+  }
+  return 0;
+}
+
+
+/*
+
+  uint8_t mui_u8g2_btn_goto_wm_fi(mui_t *ui, uint8_t msg)
+
+  Description:
+    A button with size equal to button text plus one pixel padding
+    The button has a one pixel frame around the text.
+    If the selected, then the form will change to the specified form number.
+    
+  Message Handling: DRAW, CURSOR_SELECT
+
+  Style
+    No Selection: Text + Frame
+    Cursor Selection: Inverted text + Frame
+
+  User interface field list (muif):
+    flags: MUIF_CFLAG_IS_CURSOR_SELECTABLE
+    data: not used
+
+  Field definition string (fds):
+    xy: Left position of the text (required)
+    arg: Form numner (required)
+    text: Button label
+    
+*/
+uint8_t mui_u8g2_btn_goto_wm_fi(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_utf(ui, U8G2_BTN_HCENTER |mui_u8g2_get_fi_flags(ui), 0, 1, MUI_U8G2_V_PADDING, ui->text);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      //return mui_GotoForm(ui, ui->arg, 0);
+      return mui_GotoFormAutoCursorPosition(ui, ui->arg);
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;    
+    
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_btn_goto_wm_if(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_utf(ui, U8G2_BTN_HCENTER |mui_u8g2_get_if_flags(ui), 0, 1, MUI_U8G2_V_PADDING, ui->text);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      //return mui_GotoForm(ui, ui->arg, 0);
+      return mui_GotoFormAutoCursorPosition(ui, ui->arg);
+   case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;    
+    
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_btn_goto_w2_fi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_utf(ui, U8G2_BTN_HCENTER | mui_u8g2_get_fi_flags(ui), u8g2_GetDisplayWidth(u8g2)/2 - 10, 0, MUI_U8G2_V_PADDING, ui->text);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      //return mui_GotoForm(ui, ui->arg, 0);
+      return mui_GotoFormAutoCursorPosition(ui, ui->arg);
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;    
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_btn_goto_w2_if(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_utf(ui, U8G2_BTN_HCENTER | mui_u8g2_get_if_flags(ui), u8g2_GetDisplayWidth(u8g2)/2 - 10, 0, MUI_U8G2_V_PADDING, ui->text);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      //return mui_GotoForm(ui, ui->arg, 0);
+      return mui_GotoFormAutoCursorPosition(ui, ui->arg);
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;    
+  }
+  return 0;
+}
+
+/*
+
+  uint8_t mui_u8g2_btn_exit_wm_fi(mui_t *ui, uint8_t msg)
+
+  Description:
+    A button with size equal to button text plus one pixel padding
+    The button has a one pixel frame around the text.
+    If selected, then the menu system will be closed.
+    The arg value will be stored at the specified data location (if not NULL).
+    The arg value can be used as an exit value of the button.
+    
+  Message Handling: DRAW, CURSOR_SELECT
+
+  Style
+    No Selection: Text + Frame
+    Cursor Selection: Inverted text + Frame
+
+  User interface field list (muif):
+    flags: MUIF_CFLAG_IS_CURSOR_SELECTABLE
+    data: Optionally points to uint8_t value which will receive the arg value of the field.
+
+  Field definition string (fds):
+    xy: Left position of the text (required)
+    arg: Value which will be stored at *data (optional)
+    text: Button label
+    
+*/
+uint8_t mui_u8g2_btn_exit_wm_fi(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_utf(ui, U8G2_BTN_HCENTER |mui_u8g2_get_fi_flags(ui), 0, 1, MUI_U8G2_V_PADDING, ui->text);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      {
+        uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+        if ( value != NULL )
+          *value = ui->arg;
+      }
+      mui_SaveForm(ui);          // store the current form and position so that the child can jump back
+      mui_LeaveForm(ui);
+      return 1;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;    
+  }
+  return 0;
+}
+
+
+uint8_t mui_u8g2_btn_goto_w1_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_pi(ui, u8g2_GetDisplayWidth(u8g2)-mui_get_x(ui)*2, mui_get_x(ui) , ui->text);
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), u8g2_GetDisplayWidth(u8g2)-mui_get_x(ui)*2, mui_get_x(ui) , MUI_U8G2_V_PADDING, ui->text);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      //return mui_GotoForm(ui, ui->arg, 0);
+      return mui_GotoFormAutoCursorPosition(ui, ui->arg);
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;    
+  }
+  return 0;
+}
+
+
+uint8_t mui_u8g2_btn_goto_w1_fi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_fi(ui, u8g2_GetDisplayWidth(u8g2)-mui_get_x(ui)*2, mui_get_x(ui)-1 , ui->text);
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), u8g2_GetDisplayWidth(u8g2)-mui_get_x(ui)*2, mui_get_x(ui) , MUI_U8G2_V_PADDING, ui->text);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      //return mui_GotoForm(ui, ui->arg, 0);
+      return mui_GotoFormAutoCursorPosition(ui, ui->arg);
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;    
+  }
+  return 0;
+}
+
+/*===============================================================================*/
+
+static void mui_u8g2_u8_vmm_draw_wm_pi(mui_t *ui) MUI_NOINLINE;
+static void mui_u8g2_u8_vmm_draw_wm_pi(mui_t *ui)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  mui_u8g2_u8_min_max_t *vmm= (mui_u8g2_u8_min_max_t *)muif_get_data(ui->uif);
+  char buf[4] = "999";
+  char *s = buf;
+  uint8_t *value = mui_u8g2_u8mm_get_valptr(vmm);
+  uint8_t min = mui_u8g2_u8mm_get_min(vmm);
+  uint8_t max = mui_u8g2_u8mm_get_max(vmm);
+  uint8_t cnt = 3;
+  
+  if ( *value > max ) 
+    *value = max;
+  if ( *value <= min )
+    *value = min;
+  if ( max < 100 )
+  {
+    s++;
+    cnt--;
+  }
+  if ( max < 10 )
+  {
+    s++;
+    cnt--;
+  }
+  //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), u8g2_GetStrWidth(u8g2, s)+1, 1, MUI_U8G2_V_PADDING, u8x8_u8toa(*value, cnt));
+  mui_u8g2_draw_button_pi(ui, u8g2_GetStrWidth(u8g2, s)+1, 1, u8x8_u8toa(*value, cnt));
+}
+
+
+uint8_t mui_u8g2_u8_min_max_wm_mse_pi(mui_t *ui, uint8_t msg)
+{
+  mui_u8g2_u8_min_max_t *vmm= (mui_u8g2_u8_min_max_t *)muif_get_data(ui->uif);
+  uint8_t *value = mui_u8g2_u8mm_get_valptr(vmm);
+  uint8_t min = mui_u8g2_u8mm_get_min(vmm);
+  uint8_t max = mui_u8g2_u8mm_get_max(vmm);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_vmm_draw_wm_pi(ui);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+      (*value)++;
+      if ( *value > max ) *value = min;
+      break;
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( *value > min ) (*value)--; else *value = max;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_min_max_wm_mud_pi(mui_t *ui, uint8_t msg)
+{
+  mui_u8g2_u8_min_max_t *vmm= (mui_u8g2_u8_min_max_t *)muif_get_data(ui->uif);
+  uint8_t *value = mui_u8g2_u8mm_get_valptr(vmm);
+  uint8_t min = mui_u8g2_u8mm_get_min(vmm);
+  uint8_t max = mui_u8g2_u8mm_get_max(vmm);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_vmm_draw_wm_pi(ui);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+     /* toggle between normal mode and capture next/prev mode */
+      ui->is_mud = !ui->is_mud;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      if ( ui->is_mud )
+      {
+        (*value)++;
+        if ( *value > max )
+          *value = min;
+        return 1; 
+      }
+      break;
+    case MUIF_MSG_EVENT_PREV:
+      if ( ui->is_mud )
+      {
+        if ( *value <= min )
+          *value = max;
+        else
+          (*value)--;
+        return 1;
+      }
+      break;
+  }
+  return 0;
+}
+
+
+
+static void mui_u8g2_u8_vmm_draw_wm_pf(mui_t *ui) MUI_NOINLINE;
+static void mui_u8g2_u8_vmm_draw_wm_pf(mui_t *ui)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  mui_u8g2_u8_min_max_t *vmm= (mui_u8g2_u8_min_max_t *)muif_get_data(ui->uif);
+  char buf[4] = "999";
+  char *s = buf;
+  uint8_t *value = mui_u8g2_u8mm_get_valptr(vmm);
+  uint8_t min = mui_u8g2_u8mm_get_min(vmm);
+  uint8_t max = mui_u8g2_u8mm_get_max(vmm);
+  uint8_t cnt = 3;
+  
+  if ( *value > max ) 
+    *value = max;
+  if ( *value <= min )
+    *value = min;
+  if ( max < 100 )
+  {
+    s++;
+    cnt--;
+  }
+  if ( max < 10 )
+  {
+    s++;
+    cnt--;
+  }
+  //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), u8g2_GetStrWidth(u8g2, s)+1, 1, MUI_U8G2_V_PADDING, u8x8_u8toa(*value, cnt));
+  mui_u8g2_draw_button_pf(ui, u8g2_GetStrWidth(u8g2, s)+1, 1, u8x8_u8toa(*value, cnt));
+}
+
+
+uint8_t mui_u8g2_u8_min_max_wm_mse_pf(mui_t *ui, uint8_t msg)
+{
+  mui_u8g2_u8_min_max_t *vmm= (mui_u8g2_u8_min_max_t *)muif_get_data(ui->uif);
+  uint8_t *value = mui_u8g2_u8mm_get_valptr(vmm);
+  uint8_t min = mui_u8g2_u8mm_get_min(vmm);
+  uint8_t max = mui_u8g2_u8mm_get_max(vmm);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_vmm_draw_wm_pf(ui);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+      (*value)++;
+      if ( *value > max ) *value = min;
+      break;
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( *value > min ) (*value)--; else *value = max;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_min_max_wm_mud_pf(mui_t *ui, uint8_t msg)
+{
+  mui_u8g2_u8_min_max_t *vmm= (mui_u8g2_u8_min_max_t *)muif_get_data(ui->uif);
+  uint8_t *value = mui_u8g2_u8mm_get_valptr(vmm);
+  uint8_t min = mui_u8g2_u8mm_get_min(vmm);
+  uint8_t max = mui_u8g2_u8mm_get_max(vmm);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_vmm_draw_wm_pf(ui);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      /* toggle between normal mode and capture next/prev mode */
+      ui->is_mud = !ui->is_mud;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      if ( ui->is_mud )
+      {
+        (*value)++;
+        if ( *value > max )
+          *value = min;
+        return 1;
+      }
+      break;
+    case MUIF_MSG_EVENT_PREV:
+      if ( ui->is_mud )
+      {
+        if ( *value <= min )
+          *value = max;
+        else
+          (*value)--;
+        return 1;
+      }
+      break;
+  }
+  return 0;
+}
+
+
+/*===============================================================================*/
+
+static uint8_t mui_u8g2_u8_bar_mse_msg_handler(mui_t *ui, uint8_t msg) MUI_NOINLINE;
+static uint8_t mui_u8g2_u8_bar_mse_msg_handler(mui_t *ui, uint8_t msg)
+{
+  mui_u8g2_u8_min_max_step_t *vmms= (mui_u8g2_u8_min_max_step_t *)muif_get_data(ui->uif);
+  uint8_t *value = mui_u8g2_u8mms_get_valptr(vmms);
+  uint8_t min = mui_u8g2_u8mms_get_min(vmms);
+  uint8_t max = mui_u8g2_u8mms_get_max(vmms);
+  uint8_t step = mui_u8g2_u8mms_get_step(vmms);
+  uint8_t flags = mui_u8g2_u8mms_get_flags(vmms);
+
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+      (*value)+=step;
+      if ( *value > max )
+      {
+          if ( flags & MUI_MMS_NO_WRAP )
+            *value = max;
+          else
+            *value = min;
+      }
+      break;
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( *value >= min+step ) 
+        (*value)-=step; 
+      else 
+      {
+          if ( flags & MUI_MMS_NO_WRAP )
+            *value = min;
+          else
+            *value = max;
+      }
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+static uint8_t mui_u8g2_u8_bar_mud_msg_handler(mui_t *ui, uint8_t msg) MUI_NOINLINE;
+static uint8_t mui_u8g2_u8_bar_mud_msg_handler(mui_t *ui, uint8_t msg)
+{
+  mui_u8g2_u8_min_max_step_t *vmms= (mui_u8g2_u8_min_max_step_t *)muif_get_data(ui->uif);
+  uint8_t *value = mui_u8g2_u8mms_get_valptr(vmms);
+  uint8_t min = mui_u8g2_u8mms_get_min(vmms);
+  uint8_t max = mui_u8g2_u8mms_get_max(vmms);
+  uint8_t step = mui_u8g2_u8mms_get_step(vmms);
+  uint8_t flags = mui_u8g2_u8mms_get_flags(vmms);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      /* toggle between normal mode and capture next/prev mode */
+      ui->is_mud = !ui->is_mud;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      if ( ui->is_mud )
+      {
+        (*value)+=step;
+        if ( *value > max )
+        {
+          if ( flags & MUI_MMS_NO_WRAP )
+            *value = max;
+          else
+            *value = min;
+        }
+        return 1;
+      }
+      break;
+    case MUIF_MSG_EVENT_PREV:
+      if ( ui->is_mud )
+      {
+        if ( *value <= min || *value > max)
+        {
+          if ( flags & MUI_MMS_NO_WRAP )
+            *value = min;
+          else
+            *value = max;
+        }
+        else
+          (*value)-=step;
+        return 1;
+      }
+      break;
+  }
+  return 0;
+}
+
+
+
+static void mui_u8g2_u8_bar_draw_wm(mui_t *ui, uint8_t flags, uint8_t is_fixed_width) MUI_NOINLINE;
+static void mui_u8g2_u8_bar_draw_wm(mui_t *ui, uint8_t flags, uint8_t is_fixed_width)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  mui_u8g2_u8_min_max_step_t *vmms= (mui_u8g2_u8_min_max_step_t *)muif_get_data(ui->uif);
+  char buf[4] = "999";
+  char *s = buf;
+  uint8_t *value = mui_u8g2_u8mms_get_valptr(vmms);
+  uint8_t min = mui_u8g2_u8mms_get_min(vmms);
+  uint8_t max = mui_u8g2_u8mms_get_max(vmms);
+  uint8_t scale = 0;
+  //uint8_t step = mui_u8g2_u8mms_get_step(vmms);
+  uint8_t mms_flags = mui_u8g2_u8mms_get_flags(vmms);
+  uint8_t cnt = 3;
+  uint8_t height = u8g2_GetAscent(u8g2);
+  int8_t backup_descent;
+  u8g2_uint_t x = mui_get_x(ui);
+  u8g2_uint_t w = 0;
+  u8g2_uint_t v;  // the calculated pixel value
+  
+  if ( mms_flags & MUI_MMS_2X_BAR )
+    scale |= 1;
+  if ( mms_flags & MUI_MMS_4X_BAR )
+    scale |= 2;
+  
+  if ( *value > max ) 
+    *value = max;
+  if ( *value <= min )
+    *value = min;
+  if ( max < 100 )
+  {
+    s++;
+    cnt--;
+  }
+  if ( max < 10 )
+  {
+    s++;
+    cnt--;
+  }
+
+  if ( is_fixed_width == 0 )
+  {
+    w += (max<<scale);          // total width of the bar is derived from the max value
+    v = (*value)<<scale;          // pixel position for the current value
+  }
+  else
+  {
+    u8g2_uint_t width = mui_u8g2_u8mms_get_width(vmms);
+    
+    w += (width<<scale);          // total width of bar is defined by the width argument
+    v = ((u8g2_long_t)(*value) * (u8g2_long_t)(width<<scale)) / (u8g2_long_t)max;    // u8g2_long_t is int32_t if 16 bit mode is enabled
+  }
+
+  w += 2;                               // add gap for the frame
+  
+  u8g2_DrawFrame( u8g2, x, mui_get_y(ui)-height, w, height);
+  u8g2_DrawBox( u8g2, x+1, mui_get_y(ui)-height+1, v, height-2);
+  if ( mms_flags & MUI_MMS_SHOW_VALUE )
+  {
+    w += 2;
+    u8g2_DrawStr(u8g2,  x+w, mui_get_y(ui), u8x8_u8toa(*value, cnt) );
+    w += u8g2_GetStrWidth(u8g2, s);
+    w += 1; 
+  }
+  backup_descent = u8g2->font_ref_descent;
+  u8g2->font_ref_descent = 0; /* hmm... that's a low level hack so that DrawButtonFrame ignores the descent value of the font */
+  u8g2_DrawButtonFrame(u8g2, x, mui_get_y(ui), flags, w, 1, 1);
+  u8g2->font_ref_descent = backup_descent;  
+}
+
+// #define MUIF_U8G2_U8_MIN_MAX_STEP(id, valptr, min, max, step, flags, muif)
+
+uint8_t mui_u8g2_u8_bar_wm_mse_pi(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_bar_draw_wm(ui, mui_u8g2_get_pi_flags(ui), 0);
+      break;
+    default:
+      return mui_u8g2_u8_bar_mse_msg_handler(ui, msg);
+  }
+  return 0;
+}
+
+
+uint8_t mui_u8g2_u8_bar_wm_mud_pi(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_bar_draw_wm(ui, mui_u8g2_get_pi_flags(ui), 0);
+      break;
+    default:
+      return mui_u8g2_u8_bar_mud_msg_handler(ui, msg);
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_bar_wm_mse_pf(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_bar_draw_wm(ui, mui_u8g2_get_pf_flags(ui), 0);
+      break;
+    default:
+      return mui_u8g2_u8_bar_mse_msg_handler(ui, msg);
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_bar_wm_mud_pf(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_bar_draw_wm(ui, mui_u8g2_get_pf_flags(ui), 0);
+      break;
+    default:
+      return mui_u8g2_u8_bar_mud_msg_handler(ui, msg);
+  }
+  return 0;
+}
+
+
+
+// #define MUIF_U8G2_U8_MIN_MAX_STEP_WIDTH(id, valptr, min, max, step, width, flags, muif) 
+
+
+uint8_t mui_u8g2_u8_fixed_width_bar_wm_mse_pi(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_bar_draw_wm(ui, mui_u8g2_get_pi_flags(ui), 1);
+      break;
+    default:
+      return mui_u8g2_u8_bar_mse_msg_handler(ui, msg);
+  }
+  return 0;
+}
+
+
+uint8_t mui_u8g2_u8_fixed_width_bar_wm_mud_pi(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_bar_draw_wm(ui, mui_u8g2_get_pi_flags(ui), 1);
+      break;
+    default:
+      return mui_u8g2_u8_bar_mud_msg_handler(ui, msg);
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_fixed_width_bar_wm_mse_pf(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_bar_draw_wm(ui, mui_u8g2_get_pf_flags(ui), 1);
+      break;
+    default:
+      return mui_u8g2_u8_bar_mse_msg_handler(ui, msg);
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_fixed_width_bar_wm_mud_pf(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_u8_bar_draw_wm(ui, mui_u8g2_get_pf_flags(ui), 1);
+      break;
+    default:
+      return mui_u8g2_u8_bar_mud_msg_handler(ui, msg);
+  }
+  return 0;
+}
+
+
+
+/*===============================================================================*/
+
+static uint8_t mui_is_valid_char(uint8_t c) MUI_NOINLINE;
+uint8_t mui_is_valid_char(uint8_t c)
+{
+  if ( c == 32 )
+    return 1;
+  if ( c >= 'A' && c <= 'Z' )
+    return 1;
+  if ( c >= 'a' && c <= 'z' )
+    return 1;
+  if ( c >= '0' && c <= '9' )
+    return 1;
+  return 0;
+}
+
+
+
+uint8_t mui_u8g2_u8_char_wm_mud_pi(mui_t *ui, uint8_t msg)
+{
+  //ui->dflags                          MUIF_DFLAG_IS_CURSOR_FOCUS       MUIF_DFLAG_IS_TOUCH_FOCUS
+  //mui_get_cflags(ui->uif)       MUIF_CFLAG_IS_CURSOR_SELECTABLE
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  char buf[6];
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      while( mui_is_valid_char(*value) == 0 )
+          (*value)++;
+      buf[0] = *value;
+      buf[1] = '\0';
+      mui_u8g2_draw_button_pi(ui, u8g2_GetMaxCharWidth(u8g2), 1, buf);
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), u8g2_GetMaxCharWidth(u8g2), 1, MUI_U8G2_V_PADDING, buf);
+      //u8g2_DrawButtonUTF8(u8g2, mui_get_x(ui), mui_get_y(ui), mui_u8g2_get_pi_flags(ui), u8g2_GetMaxCharWidth(u8g2), 1, MUI_U8G2_V_PADDING, buf);
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+     case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+     /* toggle between normal mode and capture next/prev mode */
+       ui->is_mud = !ui->is_mud;
+     break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      if ( ui->is_mud )
+      {
+        do {
+          (*value)++;
+        } while( mui_is_valid_char(*value) == 0 );
+        return 1;
+      }
+      break;
+    case MUIF_MSG_EVENT_PREV:
+      if ( ui->is_mud )
+      {
+        do {
+          (*value)--;
+        } while( mui_is_valid_char(*value) == 0 );
+        return 1;
+      }
+      break;
+  }
+  return 0;
+}
+
+
+
+
+
+/*
+
+  uint8_t mui_u8g2_u8_opt_line_wa_mse_pi(mui_t *ui, uint8_t msg)
+
+  Description:
+    Select one of several options. First option has value 0.
+    Only one option is visible.
+    The visible option is automatically the selected option.
+
+  Message Handling: DRAW, SELECT
+
+  Style
+    No Selection: Text only
+    Cursor Selection: Inverted text
+
+  User interface field list (muif):
+    flags: MUIF_CFLAG_IS_CURSOR_SELECTABLE
+    data: uint8_t *, pointer to a uint8_t variable, which contains the selected option 
+
+  Field definition string (fds):
+    xy: Left position of the text (required)
+    arg: total width of the selectable option (optional), 
+    text: '|' separated list of options
+    
+*/
+uint8_t mui_u8g2_u8_opt_line_wa_mse_pi(mui_t *ui, uint8_t msg)
+{
+  //u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      if ( mui_fds_get_nth_token(ui, *value) == 0 )
+      {
+        *value = 0;
+        mui_fds_get_nth_token(ui, *value);
+      }
+      mui_u8g2_draw_button_pi(ui, ui->arg, 1, ui->text);
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), ui->arg, 1, MUI_U8G2_V_PADDING, ui->text);
+      //u8g2_DrawButtonUTF8(u8g2, mui_get_x(ui), mui_get_y(ui), mui_u8g2_get_pi_flags(ui), ui->arg, 1, MUI_U8G2_V_PADDING, ui->text);
+      
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+      (*value)++;
+      if ( mui_fds_get_nth_token(ui, *value) == 0 ) 
+        *value = 0;      
+      break;
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( *value > 0 ) 
+        (*value)--;
+      else
+        (*value) = mui_fds_get_token_cnt(ui)-1;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_opt_line_wa_mse_pf(mui_t *ui, uint8_t msg)
+{
+  //u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      if ( mui_fds_get_nth_token(ui, *value) == 0 )
+      {
+        *value = 0;
+        mui_fds_get_nth_token(ui, *value);
+      }
+      mui_u8g2_draw_button_pf(ui, ui->arg, 1, ui->text);
+      
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+      (*value)++;
+      if ( mui_fds_get_nth_token(ui, *value) == 0 ) 
+        *value = 0;      
+      break;
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( *value > 0 ) 
+        (*value)--;
+      else
+        (*value) = mui_fds_get_token_cnt(ui)-1;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_opt_line_wa_mud_pi(mui_t *ui, uint8_t msg)
+{
+  //u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      if ( mui_fds_get_nth_token(ui, *value) == 0 )
+      {
+        *value = 0;
+        mui_fds_get_nth_token(ui, *value);
+      }
+      mui_u8g2_draw_button_pi(ui, ui->arg, 1, ui->text);
+      
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      /* toggle between normal mode and capture next/prev mode */
+       ui->is_mud = !ui->is_mud;
+     break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      if ( ui->is_mud )
+      {
+        (*value)++;
+        if ( mui_fds_get_nth_token(ui, *value) == 0 ) 
+          *value = 0;      
+        return 1;
+      }
+      break;
+    case MUIF_MSG_EVENT_PREV:
+      if ( ui->is_mud )
+      {
+        if ( *value == 0 )
+          *value = mui_fds_get_token_cnt(ui);
+        (*value)--;
+        return 1;
+      }
+      break;
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u8_opt_line_wa_mud_pf(mui_t *ui, uint8_t msg)
+{
+  //u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      if ( mui_fds_get_nth_token(ui, *value) == 0 )
+      {
+        *value = 0;
+        mui_fds_get_nth_token(ui, *value);
+      }
+      mui_u8g2_draw_button_pf(ui, ui->arg, 1, ui->text);
+      
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      /* toggle between normal mode and capture next/prev mode */
+       ui->is_mud = !ui->is_mud;
+     break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      if ( ui->is_mud )
+      {
+        (*value)++;
+        if ( mui_fds_get_nth_token(ui, *value) == 0 ) 
+          *value = 0;      
+        return 1;
+      }
+      break;
+    case MUIF_MSG_EVENT_PREV:
+      if ( ui->is_mud )
+      {
+        if ( *value == 0 )
+          *value = mui_fds_get_token_cnt(ui);
+        (*value)--;
+        return 1;
+      }
+      break;
+  }
+  return 0;
+}
+
+
+
+/*
+
+  uint8_t mui_u8g2_u8_chkbox_wm_pi(mui_t *ui, uint8_t msg)
+  
+  Description:
+    Checkbox with the values 0 (not selected) and 1 (selected). 
+
+  Message Handling: DRAW, SELECT
+
+  Style
+    No Selection: Plain checkbox and text
+    Cursor Selection: Checkbox and text is inverted
+
+  User interface field list (muif):
+    flags: MUIF_CFLAG_IS_CURSOR_SELECTABLE
+    data: uint8_t *, pointer to a uint8_t variable, which contains the values 0 or 1
+
+  Field definition string (fds):
+    xy: Left position of the text (required)
+    arg: not used
+    text: Optional: Text will be printed after the checkbox with a small gap
+    
+*/
+
+uint8_t mui_u8g2_u8_chkbox_wm_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  u8g2_uint_t flags = 0;
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      if ( *value > 1 ) *value = 1;
+      if ( mui_IsCursorFocus(ui) )
+      {
+        flags |= U8G2_BTN_INV;
+      }
+      
+      {
+        u8g2_uint_t w = 0;
+        u8g2_uint_t a = u8g2_GetAscent(u8g2);
+        if ( *value )
+          u8g2_DrawCheckbox(u8g2, mui_get_x(ui), mui_get_y(ui), a, 1);
+        else
+          u8g2_DrawCheckbox(u8g2, mui_get_x(ui), mui_get_y(ui), a, 0);
+        
+        if ( ui->text[0] != '\0' )
+        {
+          w =  u8g2_GetUTF8Width(u8g2, ui->text);
+          //u8g2_SetFontMode(u8g2, 1);
+          a += 2;       /* add gap between the checkbox and the text area */
+          u8g2_DrawUTF8(u8g2, mui_get_x(ui)+a, mui_get_y(ui), ui->text);
+        }
+        
+        u8g2_DrawButtonFrame(u8g2, mui_get_x(ui), mui_get_y(ui), flags, w+a, 1, MUI_U8G2_V_PADDING);
+      }
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      (*value)++;
+      if ( *value > 1 ) *value = 0;      
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+/*
+  radio button style, arg is assigned as value
+*/
+uint8_t mui_u8g2_u8_radio_wm_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  u8g2_uint_t flags = 0;
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+       if ( mui_IsCursorFocus(ui) )
+      {
+        flags |= U8G2_BTN_INV;
+      }
+      
+      {
+        u8g2_uint_t w = 0;
+        u8g2_uint_t a = u8g2_GetAscent(u8g2);
+        if ( *value == ui->arg )
+          u8g2_DrawCheckbox(u8g2, mui_get_x(ui), mui_get_y(ui), a, 1);
+        else
+          u8g2_DrawCheckbox(u8g2, mui_get_x(ui), mui_get_y(ui), a, 0);
+        
+        if ( ui->text[0] != '\0' )
+        {
+          w =  u8g2_GetUTF8Width(u8g2, ui->text);
+          //u8g2_SetFontMode(u8g2, 1);
+          a += 2;       /* add gap between the checkbox and the text area */
+          u8g2_DrawUTF8(u8g2, mui_get_x(ui)+a, mui_get_y(ui), ui->text);
+        }
+        
+        u8g2_DrawButtonFrame(u8g2, mui_get_x(ui), mui_get_y(ui), flags, w+a, 1, MUI_U8G2_V_PADDING);
+      }
+      break;
+   case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      *value = ui->arg;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;  
+}
+
+
+uint8_t mui_u8g2_u8_opt_parent_wm_pi(mui_t *ui, uint8_t msg)
+{
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      if ( mui_fds_get_nth_token(ui, *value) == 0 )
+      {
+        *value = 0;
+        mui_fds_get_nth_token(ui, *value);
+      }      
+      mui_u8g2_draw_button_pi(ui, 0, 1, ui->text);
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), 0, 1, MUI_U8G2_V_PADDING, ui->text);
+      
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      mui_SaveForm(ui);          // store the current form and position so that the child can jump back
+      mui_GotoForm(ui, ui->arg, *value);  // assumes that the selectable values are at the beginning of the form definition
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+
+uint8_t mui_u8g2_u8_opt_child_mse_common(mui_t *ui, uint8_t msg)
+{
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  uint8_t arg = ui->arg;        // remember the arg value, because it might be overwritten
+  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      /* done by the calling function */
+      break;
+    case MUIF_MSG_FORM_START:
+      /* we can assume that the list starts at the top. It will be adjisted by cursor down events later */
+      /* ui->form_scroll_top = 0 and all other form_scroll values are set to 0 if a new form is entered in mui_EnterForm() */
+      if ( ui->form_scroll_visible <= arg )
+        ui->form_scroll_visible = arg+1;
+      if ( ui->form_scroll_total == 0 )
+          ui->form_scroll_total = mui_GetSelectableFieldOptionCnt(ui, ui->last_form_fds);
+      //printf("MUIF_MSG_FORM_START: arg=%d visible=%d top=%d total=%d\n", arg, ui->form_scroll_visible, ui->form_scroll_top, ui->form_scroll_total);
+      break;
+    case MUIF_MSG_FORM_END:  
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      return mui_u8g2_handle_scroll_next_prev_events(ui, msg);
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( value != NULL )
+        *value = ui->form_scroll_top + arg;
+      mui_RestoreForm(ui);
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      return mui_u8g2_handle_scroll_next_prev_events(ui, msg);
+    case MUIF_MSG_EVENT_PREV:
+      return mui_u8g2_handle_scroll_next_prev_events(ui, msg);
+  }
+  return 0;
+}
+
+
+uint8_t mui_u8g2_u8_opt_radio_child_wm_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  uint8_t arg = ui->arg;        // remember the arg value, because it might be overwritten
+  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      {
+        u8g2_uint_t w = 0;
+        u8g2_uint_t a = u8g2_GetAscent(u8g2) - 2;
+        u8g2_uint_t x = mui_get_x(ui);   // if mui_GetSelectableFieldTextOption is called, then field vars are overwritten, so get the value
+        u8g2_uint_t y = mui_get_y(ui);  // if mui_GetSelectableFieldTextOption is called, then field vars are overwritten, so get the value
+        uint8_t is_focus = mui_IsCursorFocus(ui);
+        if ( *value == arg + ui->form_scroll_top )
+          u8g2_DrawValueMark(u8g2, x, y, a);
+
+        if ( ui->text[0] == '\0' )
+        {
+          /* if the text is not provided, then try to get the text from the previous (saved) element, assuming that this contains the selection */
+          /* this will overwrite all ui member functions, so we must not access any ui members (except ui->text) any more */
+          mui_GetSelectableFieldTextOption(ui, ui->last_form_fds, arg + ui->form_scroll_top);
+        }
+        
+        if ( ui->text[0] != '\0' )
+        {
+          w =  u8g2_GetUTF8Width(u8g2, ui->text);
+          //u8g2_SetFontMode(u8g2, 1);
+          a += 2;       /* add gap between the checkbox and the text area */
+          u8g2_DrawUTF8(u8g2, x+a, y, ui->text);
+        }        
+        if ( is_focus )
+        {
+          u8g2_DrawButtonFrame(u8g2, x, y, U8G2_BTN_INV, w+a, 1, MUI_U8G2_V_PADDING);
+        }
+      }
+      break;
+    default:
+      return mui_u8g2_u8_opt_child_mse_common(ui, msg);
+  }
+  return 0;
+}
+
+
+uint8_t mui_u8g2_u8_opt_radio_child_w1_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  uint8_t arg = ui->arg;        // remember the arg value, because it might be overwritten
+  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      {
+        //u8g2_uint_t w = 0;
+        u8g2_uint_t a = u8g2_GetAscent(u8g2) - 2;
+        u8g2_uint_t x = mui_get_x(ui);   // if mui_GetSelectableFieldTextOption is called, then field vars are overwritten, so get the value
+        u8g2_uint_t y = mui_get_y(ui);  // if mui_GetSelectableFieldTextOption is called, then field vars are overwritten, so get the value
+        uint8_t is_focus = mui_IsCursorFocus(ui);
+        
+        if ( *value == arg + ui->form_scroll_top )
+          u8g2_DrawValueMark(u8g2, x, y, a);
+
+        if ( ui->text[0] == '\0' )
+        {
+          /* if the text is not provided, then try to get the text from the previous (saved) element, assuming that this contains the selection */
+          /* this will overwrite all ui member functions, so we must not access any ui members (except ui->text) any more */
+          mui_GetSelectableFieldTextOption(ui, ui->last_form_fds, arg + ui->form_scroll_top);
+        }
+        
+        if ( ui->text[0] != '\0' )
+        {
+          //w =  u8g2_GetUTF8Width(u8g2, ui->text);
+          //u8g2_SetFontMode(u8g2, 1);
+          a += 2;       /* add gap between the checkbox and the text area */
+          u8g2_DrawUTF8(u8g2, x+a, y, ui->text);
+        }        
+        if ( is_focus )
+        {
+          u8g2_DrawButtonFrame(u8g2, 0, y, U8G2_BTN_INV, u8g2_GetDisplayWidth(u8g2), 0, MUI_U8G2_V_PADDING);
+        }
+      }
+      break;
+    default:
+      return mui_u8g2_u8_opt_child_mse_common(ui, msg);
+  }
+  return 0;
+}
+
+
+uint8_t mui_u8g2_u8_opt_child_wm_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  //uint8_t *value = (uint8_t *)muif_get_data(ui->uif);
+  uint8_t arg = ui->arg;        // remember the arg value, because it might be overwritten
+  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      {
+        //u8g2_uint_t w = 0;
+        u8g2_uint_t x = mui_get_x(ui);   // if mui_GetSelectableFieldTextOption is called, then field vars are overwritten, so get the value
+        u8g2_uint_t y = mui_get_y(ui);  // if mui_GetSelectableFieldTextOption is called, then field vars are overwritten, so get the value
+        uint8_t flags = mui_u8g2_get_pi_flags(ui);
+        //if ( mui_IsCursorFocus(ui) )
+        //{
+        //  flags = U8G2_BTN_INV;
+        //}
+
+        if ( ui->text[0] == '\0' )
+        {
+          /* if the text is not provided, then try to get the text from the previous (saved) element, assuming that this contains the selection */
+          /* this will overwrite all ui member functions, so we must not access any ui members (except ui->text) any more */
+          mui_GetSelectableFieldTextOption(ui, ui->last_form_fds, arg + ui->form_scroll_top);
+        }
+        if ( ui->text[0] != '\0' )
+        {
+          u8g2_DrawButtonUTF8(u8g2, x, y, flags, 0, 1, MUI_U8G2_V_PADDING, ui->text);
+        }        
+      }
+      break;
+    default:
+      return mui_u8g2_u8_opt_child_mse_common(ui, msg);
+  }
+  return 0;
+}
+
+/* 
+  an invisible field (which will not show anything). It should also not be selectable 
+  it just provides the menu entries, see "mui_u8g2_u8_opt_child_mse_common" and friends 
+  as a consequence it does not have width, input mode and style
+
+  MUIF: MUIF_RO()
+  FDS: MUI_DATA()
+
+  mui_u8g2_goto_parent --> mui_u8g2_goto_data
+
+  Used together with mui_u8g2_goto_form_w1_pi
+
+*/
+uint8_t mui_u8g2_goto_data(mui_t *ui, uint8_t msg)
+{
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      break;
+    case MUIF_MSG_FORM_START:
+      // store the field (and the corresponding elements) in the last_form_fds variable.
+      // last_form_fds is later used to access the elements (see mui_u8g2_u8_opt_child_mse_common and friends)
+      ui->last_form_fds = ui->fds;
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+
+/*
+mui_u8g2_goto_child_w1_mse_pi --> mui_u8g2_goto_form_w1_pi
+*/
+uint8_t mui_u8g2_goto_form_w1_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t arg = ui->arg;        // remember the arg value, because it might be overwritten  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      if ( mui_GetSelectableFieldTextOption(ui, ui->last_form_fds, arg + ui->form_scroll_top) )
+        mui_u8g2_draw_button_pi(ui, u8g2_GetDisplayWidth(u8g2)-mui_get_x(ui)*2, mui_get_x(ui), ui->text+1);
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+      if ( mui_GetSelectableFieldTextOption(ui, ui->last_form_fds, ui->arg + ui->form_scroll_top) )
+      {
+        mui_SaveCursorPosition(ui, ui->arg + ui->form_scroll_top);     // store the current cursor position, so that the user can jump back to the corresponding cursor position
+        return mui_GotoFormAutoCursorPosition(ui, (uint8_t)ui->text[0]);
+      }
+      break;
+    default:
+      return mui_u8g2_u8_opt_child_mse_common(ui, msg);
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_goto_form_w1_pf(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  uint8_t arg = ui->arg;        // remember the arg value, because it might be overwritten  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      if ( mui_GetSelectableFieldTextOption(ui, ui->last_form_fds, arg + ui->form_scroll_top) )
+        mui_u8g2_draw_button_pf(ui, u8g2_GetDisplayWidth(u8g2)-mui_get_x(ui)*2, mui_get_x(ui)-1, ui->text+1);
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+      if ( mui_GetSelectableFieldTextOption(ui, ui->last_form_fds, ui->arg + ui->form_scroll_top) )
+      {
+        mui_SaveCursorPosition(ui, ui->arg + ui->form_scroll_top);     // store the current cursor position, so that the user can jump back to the corresponding cursor position
+        return mui_GotoFormAutoCursorPosition(ui, (uint8_t)ui->text[0]);
+     }
+      break;
+    default:
+      return mui_u8g2_u8_opt_child_mse_common(ui, msg);
+  }
+  return 0;
+}
+
+
+/*
+  data: mui_u8g2_list_t *
+*/
+uint8_t mui_u8g2_u16_list_line_wa_mse_pi(mui_t *ui, uint8_t msg)
+{
+  //u8g2_t *u8g2 = mui_get_U8g2(ui);
+  mui_u8g2_list_t *list = (mui_u8g2_list_t *)muif_get_data(ui->uif);
+  uint16_t *selection =  mui_u8g2_list_get_selection_ptr(list);
+  void *data = mui_u8g2_list_get_data_ptr(list);
+  mui_u8g2_get_list_element_cb element_cb =  mui_u8g2_list_get_element_cb(list);
+  mui_u8g2_get_list_count_cb count_cb = mui_u8g2_list_get_count_cb(list);
+  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_pi(ui, ui->arg, 1, element_cb(data, *selection));
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), ui->arg, 1, MUI_U8G2_V_PADDING, element_cb(data, *selection));
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+      (*selection)++;
+      if ( *selection >= count_cb(data) ) 
+        *selection = 0;
+      break;
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( *selection > 0 )
+        (*selection)--;
+      else
+        (*selection) = count_cb(data)-1;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u16_list_line_wa_mud_pi(mui_t *ui, uint8_t msg)
+{
+  //u8g2_t *u8g2 = mui_get_U8g2(ui);
+  mui_u8g2_list_t *list = (mui_u8g2_list_t *)muif_get_data(ui->uif);
+  uint16_t *selection =  mui_u8g2_list_get_selection_ptr(list);
+  void *data = mui_u8g2_list_get_data_ptr(list);
+  mui_u8g2_get_list_element_cb element_cb =  mui_u8g2_list_get_element_cb(list);
+  mui_u8g2_get_list_count_cb count_cb = mui_u8g2_list_get_count_cb(list);
+  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_pi(ui, ui->arg, 1, element_cb(data, *selection));
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), ui->arg, 1, MUI_U8G2_V_PADDING, element_cb(data, *selection));
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      /* toggle between normal mode and capture next/prev mode */
+       ui->is_mud = !ui->is_mud;
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      if ( ui->is_mud )
+      {
+        (*selection)++;
+        if ( *selection >= count_cb(data)  ) 
+          *selection = 0;      
+        return 1;
+      }
+      break;
+    case MUIF_MSG_EVENT_PREV:
+      if ( ui->is_mud )
+      {
+        if ( *selection == 0 )
+          *selection = count_cb(data);
+        (*selection)--;
+        return 1;
+      }
+      break;
+  }
+  return 0;
+}
+
+/*
+  MUIF: MUIF_U8G2_U16_LIST
+  FDS: MUI_XYA, arg=form id
+  data: mui_u8g2_list_t *
+*/
+uint8_t mui_u8g2_u16_list_parent_wm_pi(mui_t *ui, uint8_t msg)
+{
+  //u8g2_t *u8g2 = mui_get_U8g2(ui);
+  mui_u8g2_list_t *list = (mui_u8g2_list_t *)muif_get_data(ui->uif);
+  uint16_t *selection =  mui_u8g2_list_get_selection_ptr(list);
+  void *data = mui_u8g2_list_get_data_ptr(list);
+  mui_u8g2_get_list_element_cb element_cb =  mui_u8g2_list_get_element_cb(list);
+  //mui_u8g2_get_list_count_cb count_cb = mui_u8g2_list_get_count_cb(list);
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_pi(ui, 0, 1, element_cb(data, *selection));
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), ui->arg, 1, MUI_U8G2_V_PADDING, element_cb(data, *selection));
+      break;
+    case MUIF_MSG_FORM_START:
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      mui_SaveForm(ui);          // store the current form and position so that the child can jump back
+      mui_GotoForm(ui, ui->arg, *selection);  // assumes that the selectable values are at the beginning of the form definition
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+  }
+  return 0;
+}
+
+static uint8_t mui_u8g2_u16_list_child_mse_common(mui_t *ui, uint8_t msg)
+{
+  mui_u8g2_list_t *list = (mui_u8g2_list_t *)muif_get_data(ui->uif);
+  uint16_t *selection =  mui_u8g2_list_get_selection_ptr(list);
+  void *data = mui_u8g2_list_get_data_ptr(list);
+  //mui_u8g2_get_list_element_cb element_cb =  mui_u8g2_list_get_element_cb(list);
+  mui_u8g2_get_list_count_cb count_cb = mui_u8g2_list_get_count_cb(list);
+
+  uint8_t arg = ui->arg;        // remember the arg value, because it might be overwritten  
+  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      /* done by the calling function */
+      break;
+    case MUIF_MSG_FORM_START:
+      /* we can assume that the list starts at the top. It will be adjisted by cursor down events later */
+      ui->form_scroll_top = 0;
+      if ( ui->form_scroll_visible <= arg )
+        ui->form_scroll_visible = arg+1;
+      if ( ui->form_scroll_total == 0 )
+          ui->form_scroll_total = count_cb(data);
+      break;
+    case MUIF_MSG_FORM_END:
+      break;
+    case MUIF_MSG_CURSOR_ENTER:
+      return mui_u8g2_handle_scroll_next_prev_events(ui, msg);
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( selection != NULL )
+        *selection = ui->form_scroll_top + arg;
+      mui_RestoreForm(ui);
+      break;
+    case MUIF_MSG_CURSOR_LEAVE:
+      break;
+    case MUIF_MSG_TOUCH_DOWN:
+      break;
+    case MUIF_MSG_TOUCH_UP:
+      break;
+    case MUIF_MSG_EVENT_NEXT:
+      return mui_u8g2_handle_scroll_next_prev_events(ui, msg);
+    case MUIF_MSG_EVENT_PREV:
+      return mui_u8g2_handle_scroll_next_prev_events(ui, msg);
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u16_list_child_w1_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  mui_u8g2_list_t *list = (mui_u8g2_list_t *)muif_get_data(ui->uif);
+  uint16_t *selection =  mui_u8g2_list_get_selection_ptr(list);
+  void *data = mui_u8g2_list_get_data_ptr(list);
+  mui_u8g2_get_list_element_cb element_cb =  mui_u8g2_list_get_element_cb(list);
+  mui_u8g2_get_list_count_cb count_cb = mui_u8g2_list_get_count_cb(list);
+  uint16_t pos = ui->arg;        // remember the arg value, because it might be overwritten  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      {
+        //u8g2_uint_t w = 0;
+        u8g2_uint_t a = u8g2_GetAscent(u8g2) - 2;
+        u8g2_uint_t x = mui_get_x(ui);   // if mui_GetSelectableFieldTextOption is called, then field vars are overwritten, so get the value
+        u8g2_uint_t y = mui_get_y(ui);  // if mui_GetSelectableFieldTextOption is called, then field vars are overwritten, so get the value
+        uint8_t is_focus = mui_IsCursorFocus(ui);
+
+        pos += ui->form_scroll_top;
+        
+        if ( *selection == pos )
+          u8g2_DrawValueMark(u8g2, x, y, a);
+
+        //u8g2_SetFontMode(u8g2, 1);
+        a += 2;       /* add gap between the checkbox and the text area */
+        if ( pos < count_cb(data) )
+          u8g2_DrawUTF8(u8g2, x+a, y, element_cb(data, pos));
+        if ( is_focus )
+        {
+          u8g2_DrawButtonFrame(u8g2, 0, y, U8G2_BTN_INV, u8g2_GetDisplayWidth(u8g2), 0, MUI_U8G2_V_PADDING);
+        }
+      }
+      break;
+    default:
+      return mui_u8g2_u16_list_child_mse_common(ui, msg);
+  }
+  return 0;
+}
+
+uint8_t mui_u8g2_u16_list_goto_w1_pi(mui_t *ui, uint8_t msg)
+{
+  u8g2_t *u8g2 = mui_get_U8g2(ui);
+  mui_u8g2_list_t *list = (mui_u8g2_list_t *)muif_get_data(ui->uif);
+  uint16_t *selection =  mui_u8g2_list_get_selection_ptr(list);
+  void *data = mui_u8g2_list_get_data_ptr(list);
+  mui_u8g2_get_list_element_cb element_cb =  mui_u8g2_list_get_element_cb(list);
+  //mui_u8g2_get_list_count_cb count_cb = mui_u8g2_list_get_count_cb(list);
+
+  uint16_t pos = ui->arg;        // remember the arg value, because it might be overwritten  
+  pos += ui->form_scroll_top;
+  
+  switch(msg)
+  {
+    case MUIF_MSG_DRAW:
+      mui_u8g2_draw_button_pi(ui, u8g2_GetDisplayWidth(u8g2)-mui_get_x(ui)*2, mui_get_x(ui), element_cb(data, pos)+1);
+      //mui_u8g2_draw_button_utf(ui, mui_u8g2_get_pi_flags(ui), u8g2_GetDisplayWidth(u8g2)-mui_get_x(ui)*2, mui_get_x(ui), MUI_U8G2_V_PADDING, element_cb(data, pos)+1);
+      break;
+    case MUIF_MSG_CURSOR_SELECT:
+    case MUIF_MSG_VALUE_INCREMENT:
+    case MUIF_MSG_VALUE_DECREMENT:
+      if ( selection != NULL )
+        *selection = pos;
+      mui_SaveCursorPosition(ui, pos >= 255 ? 0 : pos);     // store the current cursor position, so that the user can jump back to the corresponding cursor position
+      mui_GotoFormAutoCursorPosition(ui, (uint8_t)element_cb(data, pos)[0]); 
+      break;
+    default:
+      return mui_u8g2_u16_list_child_mse_common(ui, msg);
+  }
+  return 0;
+}

+ 307 - 0
components/u8g2/mui_u8g2.h

@@ -0,0 +1,307 @@
+/*
+
+  mui_u8g2.h
+
+  Monochrome minimal user interface: Glue code between mui and u8g2.
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2021, 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.  
+
+  Reference Manual:
+    https://github.com/olikraus/u8g2/wiki/muiref
+
+  MUIF_U8G2_LABEL()  
+    replacement for MUIF_LABEL(mui_u8g2_draw_text), 
+    used by MUI_LABEL(x,y,"text")
+    Supports UTF8
+    
+  MUIF_U8G2_FONT_STYLE(n, font) 
+    A special u8g2 style function, which replaces MUIF_STYLE, but restricts the style change to the
+    specific font argument (however, this should be good enough in most cases).
+    As usual, the style "n" can be activated with MUI_STYLE(n) in FDS.
+    Example:
+      muif_t muif_list[]  MUI_PROGMEM = {  
+          MUIF_U8G2_LABEL(),
+          MUIF_U8G2_FONT_STYLE(0, u8g2_font_5x8_tr) 
+        };
+        fds_t fds[] MUI_PROGMEM  =
+        MUI_FORM(1)
+        MUI_STYLE(0)
+        MUI_LABEL(5,12, "5x8 Font")
+        ;
+
+    
+
+
+
+*/
+
+#ifndef MUI_U8G2_H
+#define MUI_U8G2_H
+
+#include "mui.h"
+
+/*==========================================*/
+/* C++ compatible */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define MUI_U8G2_COMMA ,
+
+typedef const char * (*mui_u8g2_get_list_element_cb)(void *data, uint16_t index);
+typedef uint16_t (*mui_u8g2_get_list_count_cb)(void *data);
+
+struct mui_u8g2_list_struct
+{
+  uint16_t *selection;
+  void *data;
+  mui_u8g2_get_list_element_cb get_list_element;
+  mui_u8g2_get_list_count_cb get_list_count;  
+} MUI_PROGMEM;
+
+typedef const struct mui_u8g2_list_struct mui_u8g2_list_t;
+
+#if defined(__GNUC__) && defined(__AVR__)
+#  define mui_u8g2_list_get_selection_ptr(list)         ((uint16_t *)mui_pgm_wread(&((list)->selection)))
+#  define mui_u8g2_list_get_data_ptr(list)                ((void *)mui_pgm_wread(&((list)->data)))
+#  define mui_u8g2_list_get_element_cb(list)          ((mui_u8g2_get_list_element_cb)mui_pgm_wread(&((list)->get_list_element)))
+#  define mui_u8g2_list_get_count_cb(list)              ((mui_u8g2_get_list_count_cb)mui_pgm_wread(&((list)->get_list_count)))
+#else
+#  define mui_u8g2_list_get_selection_ptr(list)                 ((list)->selection)
+#  define mui_u8g2_list_get_data_ptr(list)                         ((list)->data)
+#  define mui_u8g2_list_get_element_cb(list)                   ((list)->get_list_element)
+#  define mui_u8g2_list_get_count_cb(list)                      ((list)->get_list_count)
+#endif
+
+
+struct mui_u8g2_u8_min_max_struct
+{
+  uint8_t *value;
+  uint8_t min;
+  uint8_t max;
+} MUI_PROGMEM;
+
+typedef const struct mui_u8g2_u8_min_max_struct mui_u8g2_u8_min_max_t;
+
+#if defined(__GNUC__) && defined(__AVR__)
+#  define mui_u8g2_u8mm_get_min(u8mm) mui_pgm_read(&((u8mm)->min))
+#  define mui_u8g2_u8mm_get_max(u8mm) mui_pgm_read(&((u8mm)->max))
+#  define mui_u8g2_u8mm_get_valptr(u8mm) ((uint8_t *)mui_pgm_wread(&((u8mm)->value)))
+#else
+#  define mui_u8g2_u8mm_get_min(u8mm) ((u8mm)->min)
+#  define mui_u8g2_u8mm_get_max(u8mm) ((u8mm)->max)
+#  define mui_u8g2_u8mm_get_valptr(u8mm) ((u8mm)->value)
+#endif
+
+
+struct mui_u8g2_u8_min_max_step_struct
+{
+  uint8_t *value;
+  uint8_t min;
+  uint8_t max;
+  uint8_t step;
+  uint8_t flags;
+  uint8_t width;        // added with issue 2200, might not be used by all bar graph functions
+} MUI_PROGMEM;
+
+typedef const struct mui_u8g2_u8_min_max_step_struct mui_u8g2_u8_min_max_step_t;
+
+/* list of bit values for the "flags" variable */
+#define MUI_MMS_2X_BAR 0x01
+#define MUI_MMS_4X_BAR 0x02
+#define MUI_MMS_SHOW_VALUE 0x04
+#define MUI_MMS_NO_WRAP 0x08
+
+#if defined(__GNUC__) && defined(__AVR__)
+#  define mui_u8g2_u8mms_get_width(u8mm) mui_pgm_read(&((u8mm)->width))
+#  define mui_u8g2_u8mms_get_step(u8mm) mui_pgm_read(&((u8mm)->step))
+#  define mui_u8g2_u8mms_get_flags(u8mm) mui_pgm_read(&((u8mm)->flags))
+#  define mui_u8g2_u8mms_get_min(u8mm) mui_pgm_read(&((u8mm)->min))
+#  define mui_u8g2_u8mms_get_max(u8mm) mui_pgm_read(&((u8mm)->max))
+#  define mui_u8g2_u8mms_get_valptr(u8mm) ((uint8_t *)mui_pgm_wread(&((u8mm)->value)))
+#else
+#  define mui_u8g2_u8mms_get_width(u8mm) ((u8mm)->width)
+#  define mui_u8g2_u8mms_get_step(u8mm) ((u8mm)->step)
+#  define mui_u8g2_u8mms_get_flags(u8mm) ((u8mm)->flags)
+#  define mui_u8g2_u8mms_get_min(u8mm) ((u8mm)->min)
+#  define mui_u8g2_u8mms_get_max(u8mm) ((u8mm)->max)
+#  define mui_u8g2_u8mms_get_valptr(u8mm) ((u8mm)->value)
+#endif
+
+
+
+
+/* helper functions */
+
+u8g2_uint_t mui_get_x(mui_t *ui);
+u8g2_uint_t mui_get_y(mui_t *ui);
+u8g2_t *mui_get_U8g2(mui_t *ui);
+
+void mui_u8g2_draw_button_utf(mui_t *ui, u8g2_uint_t flags, u8g2_uint_t width, u8g2_uint_t padding_h, u8g2_uint_t padding_v, const char *text);
+u8g2_uint_t mui_u8g2_get_pi_flags(mui_t *ui);
+void mui_u8g2_draw_button_pi(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text);
+u8g2_uint_t mui_u8g2_get_fi_flags(mui_t *ui);
+void mui_u8g2_draw_button_fi(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text);
+u8g2_uint_t mui_u8g2_get_pf_flags(mui_t *ui);
+void mui_u8g2_draw_button_pf(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text);
+u8g2_uint_t mui_u8g2_get_if_flags(mui_t *ui);
+void mui_u8g2_draw_button_if(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h, const char *text);
+
+
+
+/* ready to use field functions */
+
+uint8_t mui_u8g2_draw_text(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_btn_goto_wm_fi(mui_t *ui, uint8_t msg);        /* GIF */
+uint8_t mui_u8g2_btn_goto_wm_if(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_btn_goto_w2_fi(mui_t *ui, uint8_t msg);         /* GIF */
+uint8_t mui_u8g2_btn_goto_w2_if(mui_t *ui, uint8_t msg);
+
+uint8_t mui_u8g2_btn_goto_w1_pi(mui_t *ui, uint8_t msg);        /* GIF */
+uint8_t mui_u8g2_btn_goto_w1_fi(mui_t *ui, uint8_t msg);        /* GIF */
+
+uint8_t mui_u8g2_btn_exit_wm_fi(mui_t *ui, uint8_t msg);        /* similar to 'mui_u8g2_btn_goto_wm_fi' but will exit the menu system */
+
+uint8_t mui_u8g2_u8_chkbox_wm_pi(mui_t *ui, uint8_t msg);       /* GIF, MUIF_VARIABLE, MUI_XY */
+uint8_t mui_u8g2_u8_radio_wm_pi(mui_t *ui, uint8_t msg);        /* GIF, MUIF_VARIABLE,MUI_XYAT */
+
+
+
+uint8_t mui_u8g2_u8_opt_line_wa_mse_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
+uint8_t mui_u8g2_u8_opt_line_wa_mse_pf(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
+uint8_t mui_u8g2_u8_opt_line_wa_mud_pi(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
+uint8_t mui_u8g2_u8_opt_line_wa_mud_pf(mui_t *ui, uint8_t msg); /* GIF, MUIF_VARIABLE,MUI_XYAT */
+
+/* dropdown list / combo box */
+/* The text part of the parent defines a '|' separated list of elements, which can be selected by the child. */
+/* Argument is a form number where the child element is placed multiple times */ 
+/* The child form does not require the ok button, because the child function will return to the parent with the select element */
+uint8_t mui_u8g2_u8_opt_parent_wm_pi(mui_t *ui, uint8_t msg);       /* GIF, MUIF_VARIABLE, MUI_XYAT */
+uint8_t mui_u8g2_u8_opt_radio_child_wm_pi(mui_t *ui, uint8_t msg);        /* GIF, MUIF_VARIABLE, MUI_XYA */
+uint8_t mui_u8g2_u8_opt_radio_child_w1_pi(mui_t *ui, uint8_t msg);          /* GIF, MUIF_VARIABLE, MUI_XYA */
+uint8_t mui_u8g2_u8_opt_child_wm_pi(mui_t *ui, uint8_t msg);                /* MUIF_VARIABLE, MUI_XYA */ 
+/* Note: there is no opt_child_goto muif, because this can be done with mui_u8g2_goto_form_w1_pi */
+
+/* (scrollable) jump menu */
+/* The text part of the parent defines a '|' separated list of elements, which can be selected goto_form functions. */
+/* Each '|' separated element must be prefixed with the form number (MUI_x) */
+uint8_t mui_u8g2_goto_data(mui_t *ui, uint8_t msg);                        /* REF, MUIF_RO, MUI_DATA (WARNING: Must appear only once per form!!! */
+uint8_t mui_u8g2_goto_form_w1_pi(mui_t *ui, uint8_t msg);          /* REF, MUIF_BUTTON, MUI_XYA */
+uint8_t mui_u8g2_goto_form_w1_pf(mui_t *ui, uint8_t msg);           /* REF, MUIF_BUTTON, MUI_XYA */
+
+
+/* character input */
+uint8_t mui_u8g2_u8_char_wm_mud_pi(mui_t *ui, uint8_t msg);     /* GIF, MUIF_VARIABLE,MUI_XY, usually requires a monospaced font line profont12 */
+
+
+/*===== MUIF U8g2 Label  =====*/
+
+#define MUIF_U8G2_LABEL()  MUIF_LABEL(mui_u8g2_draw_text)
+
+
+/*===== data = u8g2 font data  =====*/
+
+//#define MUIF_U8G2_FONT_STYLE(n,font)  MUIF("S" #n, 0, (void *)(font), mui_u8g2_set_font_style_function) 
+#define MUIF_U8G2_FONT_STYLE(n, font) { 'S', #n[0], 0, 0, (void *)(font), mui_u8g2_set_font_style_function} 
+
+
+uint8_t mui_u8g2_set_font_style_function(mui_t *ui, uint8_t msg);
+
+
+/*===== data = mui_u8g2_u8_min_max_t*  =====*/
+
+/* gcc note: the macro uses array compound literals to extend the lifetime in C++, see last section in https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html */
+#define MUIF_U8G2_U8_MIN_MAX(id, valptr, min, max, muif) \
+  MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE,  \
+  (void *)((mui_u8g2_u8_min_max_t [] ) {{ (valptr) MUI_U8G2_COMMA (min) MUI_U8G2_COMMA (max)}}), \
+  (muif))
+
+uint8_t mui_u8g2_u8_min_max_wm_mse_pi(mui_t *ui, uint8_t msg);   /* GIF, MUIF_U8G2_U8_MIN_MAX, MUI_XY */
+uint8_t mui_u8g2_u8_min_max_wm_mud_pi(mui_t *ui, uint8_t msg);  /* GIF, MUIF_U8G2_U8_MIN_MAX, MUI_XY */
+
+uint8_t mui_u8g2_u8_min_max_wm_mse_pf(mui_t *ui, uint8_t msg);  /* GIF, MUIF_U8G2_U8_MIN_MAX, MUI_XY */
+uint8_t mui_u8g2_u8_min_max_wm_mud_pf(mui_t *ui, uint8_t msg);  /* GIF, MUIF_U8G2_U8_MIN_MAX, MUI_XY */
+
+/*===== data = mui_u8g2_u8_min_max_step_t*  =====*/
+
+/* gcc note: the macro uses array compound literals to extend the lifetime in C++, see last section in https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html */
+#define MUIF_U8G2_U8_MIN_MAX_STEP(id, valptr, min, max, step, flags, muif) \
+  MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE,  \
+  (void *)((mui_u8g2_u8_min_max_step_t [] ) {{ (valptr) MUI_U8G2_COMMA (min) MUI_U8G2_COMMA (max) MUI_U8G2_COMMA (step) MUI_U8G2_COMMA (flags) MUI_U8G2_COMMA (0) }}), \
+  (muif))
+  
+
+uint8_t mui_u8g2_u8_bar_wm_mse_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_u8_bar_wm_mud_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_u8_bar_wm_mse_pf(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_u8_bar_wm_mud_pf(mui_t *ui, uint8_t msg);
+
+
+#define MUIF_U8G2_U8_MIN_MAX_STEP_WIDTH(id, valptr, min, max, step, width, flags, muif) \
+  MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE,  \
+  (void *)((mui_u8g2_u8_min_max_step_t [] ) {{ (valptr) MUI_U8G2_COMMA (min) MUI_U8G2_COMMA (max) MUI_U8G2_COMMA (step) MUI_U8G2_COMMA (flags) MUI_U8G2_COMMA (width) }}), \
+  (muif))
+  
+
+uint8_t mui_u8g2_u8_fixed_width_bar_wm_mse_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_u8_fixed_width_bar_wm_mud_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_u8_fixed_width_bar_wm_mse_pf(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_u8_fixed_width_bar_wm_mud_pf(mui_t *ui, uint8_t msg);
+
+
+
+/*===== data = mui_u8g2_list_t*  =====*/
+/* similar to mui_u8g2_u8_opt_line, but u16 and dynamic list */
+
+
+#define MUIF_U8G2_U16_LIST(id, valptr, dataptr, getcb, cntcb, muif) \
+  MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE,  \
+  (void *)((mui_u8g2_list_t [] ) {{ (valptr) MUI_U8G2_COMMA (dataptr) MUI_U8G2_COMMA (getcb) MUI_U8G2_COMMA (cntcb)}}), \
+  (muif))
+  
+uint8_t mui_u8g2_u16_list_line_wa_mse_pi(mui_t *ui, uint8_t msg);       /* GIF, MUIF_U8G2_U16_LIST, MUI_XYA, arg=pixel fieldsize */
+uint8_t mui_u8g2_u16_list_line_wa_mud_pi(mui_t *ui, uint8_t msg);       /* GIF, MUIF_U8G2_U16_LIST, MUI_XYA, arg=pixel fieldsize */
+
+
+/* dropdown list / combo box with 16 size and callback functions for MUIF_U8G2_U16_LIST */
+uint8_t mui_u8g2_u16_list_parent_wm_pi(mui_t *ui, uint8_t msg);     /* GIF, MUIF_U8G2_U16_LIST, MUI_XYA, arg=subform */
+uint8_t mui_u8g2_u16_list_child_w1_pi(mui_t *ui, uint8_t msg);      /* GIF, MUIF_U8G2_U16_LIST, MUI_XYA, arg=sub element number */
+uint8_t mui_u8g2_u16_list_goto_w1_pi(mui_t *ui, uint8_t msg);               /* REF, MUIF_U8G2_U16_LIST first char of the string denotes the target form */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MUI_U8G2_H */
+

+ 411 - 14
components/u8g2/u8g2.h

@@ -174,7 +174,7 @@
   A frame of width 9 would place the C a little bit more to the right (width of that "C" are 6 pixel).
   A frame of width 9 would place the C a little bit more to the right (width of that "C" are 6 pixel).
   If U8G2_BALANCED_STR_WIDTH_CALCULATION is defined, the width of "C" is returned as 8.
   If U8G2_BALANCED_STR_WIDTH_CALCULATION is defined, the width of "C" is returned as 8.
   
   
-  Not defining U8G2_BALANCED_STR_WIDTH_CALCULATION would fall back to the old bahavior.
+  Not defining U8G2_BALANCED_STR_WIDTH_CALCULATION would fall back to the old behavior.
 */
 */
 #ifndef U8G2_NO_BALANCED_STR_WIDTH_CALCULATION 
 #ifndef U8G2_NO_BALANCED_STR_WIDTH_CALCULATION 
 #define U8G2_BALANCED_STR_WIDTH_CALCULATION
 #define U8G2_BALANCED_STR_WIDTH_CALCULATION
@@ -343,9 +343,9 @@ struct u8g2_struct
   u8g2_uint_t width;
   u8g2_uint_t width;
   u8g2_uint_t height;
   u8g2_uint_t height;
   
   
-  /* ths is the clip box for the user to check if a specific box has an intersection */
+  /* this is the clip box for the user to check if a specific box has an intersection */
   /* use u8g2_IsIntersection from u8g2_intersection.c to test against this intersection */
   /* use u8g2_IsIntersection from u8g2_intersection.c to test against this intersection */
-  /* actually, this window describes the positon of the current page */
+  /* actually, this window describes the position of the current page */
   u8g2_uint_t user_x0;	/* left corner of the buffer */
   u8g2_uint_t user_x0;	/* left corner of the buffer */
   u8g2_uint_t user_x1;	/* right corner of the buffer (excluded) */
   u8g2_uint_t user_x1;	/* right corner of the buffer (excluded) */
   u8g2_uint_t user_y0;	/* upper edge of the buffer */
   u8g2_uint_t user_y0;	/* upper edge of the buffer */
@@ -450,8 +450,8 @@ extern const u8g2_cb_t u8g2_cb_mirror_vertical;
 #define U8G2_MIRROR	(&u8g2_cb_mirror)
 #define U8G2_MIRROR	(&u8g2_cb_mirror)
 #define U8G2_MIRROR_VERTICAL	(&u8g2_cb_mirror_vertical)
 #define U8G2_MIRROR_VERTICAL	(&u8g2_cb_mirror_vertical)
 /*
 /*
-  u8g2:			A new, not yet initialized u8g2 memory areay
-  buf:			Memory are of size tile_buf_height*<width of the display in pixel>
+  u8g2:			A new, not yet initialized u8g2 memory area
+  buf:			Memory area of size tile_buf_height*<width of the display in pixel>
   tile_buf_height:	Number of full lines
   tile_buf_height:	Number of full lines
   ll_hvline_cb:		one of:
   ll_hvline_cb:		one of:
     u8g2_ll_hvline_vertical_top_lsb
     u8g2_ll_hvline_vertical_top_lsb
@@ -485,6 +485,9 @@ uint8_t *u8g2_m_255_2_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_9_5_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_9_5_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_9_5_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_9_5_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_9_5_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_9_5_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_12_5_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_12_5_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_12_5_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_4_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_4_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_4_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_4_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_4_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_4_f(uint8_t *page_cnt);
@@ -500,6 +503,9 @@ uint8_t *u8g2_m_10_16_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_16_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_16_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_16_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_16_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_16_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_16_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_20_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_20_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_20_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_20_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_20_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_20_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_20_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_20_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_20_f(uint8_t *page_cnt);
@@ -518,6 +524,9 @@ uint8_t *u8g2_m_6_8_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_2_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_2_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_2_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_2_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_2_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_2_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_12_4_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_12_4_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_12_4_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_12_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_12_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_12_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_12_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_12_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_16_12_f(uint8_t *page_cnt);
@@ -527,6 +536,15 @@ uint8_t *u8g2_m_32_4_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_8_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_8_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_8_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_8_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_8_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_8_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_5_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_5_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_5_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_18_4_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_18_4_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_18_4_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_4_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_4_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_4_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_24_4_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_24_4_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_24_4_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_24_4_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_24_4_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_24_4_f(uint8_t *page_cnt);
@@ -581,9 +599,18 @@ uint8_t *u8g2_m_17_4_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_17_8_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_17_8_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_17_8_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_17_8_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_17_8_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_17_8_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_17_9_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_17_9_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_17_9_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_17_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_17_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_17_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_17_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_17_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_17_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_48_20_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_48_20_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_48_20_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_42_20_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_42_20_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_42_20_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_12_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_12_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_12_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_12_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_12_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_12_f(uint8_t *page_cnt);
@@ -593,18 +620,18 @@ uint8_t *u8g2_m_32_20_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_13_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_13_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_13_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_13_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_13_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_13_f(uint8_t *page_cnt);
-uint8_t *u8g2_m_19_4_1(uint8_t *page_cnt);
-uint8_t *u8g2_m_19_4_2(uint8_t *page_cnt);
-uint8_t *u8g2_m_19_4_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_10_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_10_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_10_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_10_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_10_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_10_f(uint8_t *page_cnt);
-uint8_t *u8g2_m_20_4_1(uint8_t *page_cnt);
-uint8_t *u8g2_m_20_4_2(uint8_t *page_cnt);
-uint8_t *u8g2_m_20_4_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_19_4_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_19_4_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_19_4_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_17_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_17_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_17_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_17_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_17_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_17_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_26_5_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_26_5_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_26_5_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_9_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_9_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_9_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_9_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_9_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_22_9_f(uint8_t *page_cnt);
@@ -614,6 +641,9 @@ uint8_t *u8g2_m_25_25_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_37_16_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_37_16_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_37_16_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_37_16_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_37_16_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_37_16_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_40_25_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_40_25_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_40_25_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_1_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_1_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_1_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_1_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_1_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_8_1_f(uint8_t *page_cnt);
@@ -623,6 +653,15 @@ uint8_t *u8g2_m_4_1_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_1_1_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_1_1_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_1_1_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_1_1_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_1_1_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_1_1_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_2_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_2_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_2_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_7_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_7_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_7_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_6_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_6_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_6_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_30_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_30_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_30_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_30_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_30_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_48_30_f(uint8_t *page_cnt);
@@ -677,12 +716,30 @@ void u8g2_Setup_ssd1306_i2c_128x64_alt0_2(u8g2_t *u8g2, const u8g2_cb_t *rotatio
 void u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_128x64_vcomh0_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_128x64_vcomh0_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_128x64_alt0_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_128x64_alt0_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1312_128x64_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1312_128x64_noname_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1312_128x64_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1312_i2c_128x64_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1312_i2c_128x64_noname_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1312_i2c_128x64_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_72x40_er_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_72x40_er_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_72x40_er_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_72x40_er_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_72x40_er_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_72x40_er_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_72x40_er_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_72x40_er_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_72x40_er_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_72x40_er_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_72x40_er_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1306_i2c_72x40_er_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_96x40_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_96x39_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_96x40_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_96x39_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_96x40_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_96x39_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_i2c_96x40_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_i2c_96x39_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_i2c_96x40_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_i2c_96x39_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_i2c_96x40_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1306_i2c_96x39_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1106_128x64_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1106_128x64_noname_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1106_128x64_vcomh0_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1106_128x64_vcomh0_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1106_128x64_winstar_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1106_128x64_winstar_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -720,17 +777,29 @@ void u8g2_Setup_sh1107_i2c_64x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x
 void u8g2_Setup_sh1107_i2c_64x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_64x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_64x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_64x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_seeed_96x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_seeed_96x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_hjr_oel1m0201_96x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_seeed_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_seeed_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_hjr_oel1m0201_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_seeed_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_seeed_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_hjr_oel1m0201_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_seeed_96x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_seeed_96x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_i2c_hjr_oel1m0201_96x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_seeed_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_seeed_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_i2c_hjr_oel1m0201_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_seeed_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_seeed_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_i2c_hjr_oel1m0201_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_128x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_128x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_tk078f288_80x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_128x80_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_128x80_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_tk078f288_80x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_128x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_128x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_tk078f288_80x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_128x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_128x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_i2c_tk078f288_80x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_128x80_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_128x80_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_i2c_tk078f288_80x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_128x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_128x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1107_i2c_tk078f288_80x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_pimoroni_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_pimoroni_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_seeed_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_seeed_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -749,6 +818,12 @@ void u8g2_Setup_sh1107_i2c_seeed_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotati
 void u8g2_Setup_sh1107_i2c_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_pimoroni_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_pimoroni_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_seeed_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1107_i2c_seeed_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1108_128x160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1108_128x160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1108_128x160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1108_i2c_128x160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1108_i2c_128x160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sh1108_i2c_128x160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1108_160x160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1108_160x160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1108_160x160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1108_160x160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1108_160x160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sh1108_160x160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -833,6 +908,12 @@ void u8g2_Setup_ssd1316_128x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_m
 void u8g2_Setup_ssd1316_i2c_128x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1316_i2c_128x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1316_i2c_128x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1316_i2c_128x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1316_i2c_128x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1316_i2c_128x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1316_96x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1316_96x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1316_96x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1316_i2c_96x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1316_i2c_96x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1316_i2c_96x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1317_96x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1317_96x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1317_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1317_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1317_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1317_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -883,12 +964,15 @@ void u8g2_Setup_ssd1327_i2c_seeed_96x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotatio
 void u8g2_Setup_ssd1327_i2c_seeed_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_i2c_seeed_96x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ea_w128128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ea_w128128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_midas_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_midas_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1327_zjy_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ws_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ws_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ea_w128128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ea_w128128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_midas_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_midas_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1327_zjy_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ws_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ws_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ea_w128128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ea_w128128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_midas_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_midas_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1327_zjy_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ws_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_ws_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_i2c_ea_w128128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_i2c_ea_w128128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_i2c_midas_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1327_i2c_midas_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -923,6 +1007,12 @@ void u8g2_Setup_ld7032_i2c_60x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8
 void u8g2_Setup_ld7032_i2c_60x32_alt_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ld7032_i2c_60x32_alt_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ld7032_i2c_60x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ld7032_i2c_60x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ld7032_i2c_60x32_alt_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ld7032_i2c_60x32_alt_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ld7032_128x36_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ld7032_128x36_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ld7032_128x36_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ld7032_i2c_128x36_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ld7032_i2c_128x36_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ld7032_i2c_128x36_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_256x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_256x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_256x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_256x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_256x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_256x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -932,6 +1022,24 @@ void u8g2_Setup_st7920_256x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_ms
 void u8g2_Setup_st7920_s_256x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_s_256x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_s_256x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_s_256x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_s_256x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_s_256x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_p_144x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_p_144x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_p_144x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_144x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_144x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_144x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_s_144x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_s_144x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_s_144x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_p_160x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_p_160x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_p_160x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_160x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_160x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_160x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_s_160x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_s_160x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7920_s_160x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_192x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_192x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_192x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_192x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_192x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7920_p_192x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1022,6 +1130,12 @@ void u8g2_Setup_uc1638_192x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_ms
 void u8g2_Setup_uc1638_i2c_192x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1638_i2c_192x96_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1638_i2c_192x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1638_i2c_192x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1638_i2c_192x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1638_i2c_192x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_uc1638_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_uc1638_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_uc1638_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_uc1638_i2c_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_uc1638_i2c_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_uc1638_i2c_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1610_ea_dogxl160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1610_ea_dogxl160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1610_ea_dogxl160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1610_ea_dogxl160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1610_ea_dogxl160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1610_ea_dogxl160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1115,6 +1229,12 @@ void u8g2_Setup_st7565_jlx12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 void u8g2_Setup_st7565_nhd_c12832_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7565_nhd_c12832_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7565_nhd_c12832_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7565_nhd_c12832_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7565_nhd_c12832_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7565_nhd_c12832_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7539_192x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7539_192x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7539_192x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7539_i2c_192x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7539_i2c_192x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7539_i2c_192x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1601_128x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1601_128x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1601_128x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1601_128x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1601_128x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1601_128x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1133,6 +1253,9 @@ void u8g2_Setup_st7565_ea_dogm132_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x
 void u8g2_Setup_st7567_pi_132x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_pi_132x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_pi_132x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_pi_132x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_pi_132x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_pi_132x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_pi_132x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_pi_132x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_pi_132x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_jlx12864_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_jlx12864_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_enh_dg128064_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_enh_dg128064_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_enh_dg128064i_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_enh_dg128064i_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1145,6 +1268,30 @@ void u8g2_Setup_st7567_jlx12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 void u8g2_Setup_st7567_enh_dg128064_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_enh_dg128064_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_enh_dg128064i_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_enh_dg128064i_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_os12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_os12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_jlx12864_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_enh_dg128064_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_enh_dg128064i_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_os12864_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_jlx12864_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_enh_dg128064_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_enh_dg128064i_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_os12864_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_jlx12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_enh_dg128064_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_enh_dg128064i_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_os12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_erc13232_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_erc13232_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_erc13232_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_erc13232_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_erc13232_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_erc13232_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_122x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_122x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_122x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_122x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_122x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_122x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_64x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_64x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_hem6432_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_hem6432_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_64x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_64x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1157,6 +1304,12 @@ void u8g2_Setup_st7567_i2c_64x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8
 void u8g2_Setup_st7567_i2c_hem6432_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_i2c_hem6432_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_i2c_64x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_i2c_64x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_i2c_hem6432_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7567_i2c_hem6432_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_lw12832_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_lw12832_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_lw12832_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_lw12832_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_lw12832_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7567_i2c_lw12832_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7571_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7571_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7571_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7571_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7571_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7571_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1172,12 +1325,18 @@ void u8g2_Setup_st7571_i2c_128x96_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x
 void u8g2_Setup_st7586s_s028hn118a_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_s028hn118a_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_s028hn118a_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_s028hn118a_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_s028hn118a_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_s028hn118a_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7586s_jlx384160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7586s_jlx384160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7586s_jlx384160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_erc240160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_erc240160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_ymc240160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_ymc240160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_erc240160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_erc240160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_ymc240160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_ymc240160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_erc240160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_erc240160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_ymc240160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7586s_ymc240160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7586s_jlx320160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7586s_jlx320160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7586s_jlx320160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7588_jlx12864_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7588_jlx12864_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7588_jlx12864_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7588_jlx12864_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7588_jlx12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st7588_jlx12864_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1244,6 +1403,12 @@ void u8g2_Setup_st75256_jlx19296_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8
 void u8g2_Setup_st75256_i2c_jlx19296_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75256_i2c_jlx19296_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75256_i2c_jlx19296_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75256_i2c_jlx19296_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75256_i2c_jlx19296_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75256_i2c_jlx19296_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75256_jlx16080_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75256_jlx16080_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75256_jlx16080_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75256_i2c_jlx16080_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75256_i2c_jlx16080_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75256_i2c_jlx16080_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75320_jlx320240_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75320_jlx320240_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75320_jlx320240_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75320_jlx320240_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75320_jlx320240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75320_jlx320240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1256,6 +1421,9 @@ void u8g2_Setup_nt7534_tg12864r_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 void u8g2_Setup_ist3020_erc19264_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist3020_erc19264_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist3020_erc19264_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist3020_erc19264_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist3020_erc19264_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist3020_erc19264_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ist3088_320x240_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ist3088_320x240_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ist3088_320x240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist7920_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist7920_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist7920_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist7920_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist7920_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ist7920_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1289,6 +1457,9 @@ void u8g2_Setup_lc7981_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_m
 void u8g2_Setup_lc7981_240x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_lc7981_240x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_lc7981_240x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_lc7981_240x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_lc7981_240x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_lc7981_240x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_lc7981_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_lc7981_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_lc7981_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1307,18 +1478,42 @@ void u8g2_Setup_t6963_128x64_alt_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8
 void u8g2_Setup_t6963_160x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_160x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_160x80_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_160x80_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_160x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_t6963_160x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_t6963_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_t6963_128x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_t6963_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x32_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x32_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x132_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x132_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x132_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x132_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x132_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1320_160x132_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1320_160x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1320_160x80_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1320_160x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1320_i2c_160x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1320_i2c_160x80_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1320_i2c_160x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1322_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1322_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1322_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_256x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_256x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_256x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_256x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_256x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_256x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_128x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_128x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_128x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_128x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_128x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1322_nhd_128x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_256x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_256x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_256x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_i2c_256x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_i2c_256x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_i2c_256x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_206x36_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_206x36_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_206x36_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_i2c_206x36_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_i2c_206x36_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1362_i2c_206x36_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1606_172x72_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1606_172x72_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1606_172x72_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1606_172x72_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1606_172x72_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1606_172x72_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1340,12 +1535,18 @@ void u8g2_Setup_il3820_v2_296x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x
 void u8g2_Setup_sed1330_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sed1330_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sed1330_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sed1330_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sed1330_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_sed1330_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sed1330_256x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sed1330_256x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sed1330_256x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_nhd_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_nhd_240x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_nhd_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_nhd_240x128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_nhd_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_nhd_240x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_320x240_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_320x240_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_320x240_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_320x240_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_320x240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ra8835_320x240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sed1330_320x200_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sed1330_320x200_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_sed1330_320x200_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_64x8_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_64x8_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_64x8_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_64x8_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_64x8_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_64x8_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1355,6 +1556,9 @@ void u8g2_Setup_max7219_32x8_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg
 void u8g2_Setup_max7219_8x8_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_8x8_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_8x8_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_8x8_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_8x8_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_max7219_8x8_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_s1d15300_lm6023_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_s1d15300_lm6023_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_s1d15300_lm6023_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_s1d15e06_160100_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_s1d15e06_160100_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_s1d15e06_160100_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_s1d15e06_160100_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_s1d15e06_160100_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_s1d15e06_160100_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1364,6 +1568,18 @@ void u8g2_Setup_s1d15721_240x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 void u8g2_Setup_gu800_128x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_gu800_128x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_gu800_128x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_gu800_128x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_gu800_128x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_gu800_128x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gu800_160x16_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gu800_160x16_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gu800_160x16_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1287ai_256x50_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1287ai_256x50_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1287ai_256x50_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1247ai_253x63_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1247ai_253x63_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1247ai_253x63_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1294ai_256x48_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1294ai_256x48_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_gp1294ai_256x48_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_a2printer_384x240_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_a2printer_384x240_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_a2printer_384x240_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_a2printer_384x240_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_a2printer_384x240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_a2printer_384x240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1416,7 +1632,7 @@ void u8g2_WriteBufferXBM2(u8g2_t *u8g2, void (*out)(const char *s));
   len		length of the line in pixel, len must not be 0
   len		length of the line in pixel, len must not be 0
   dir		0: horizontal line (left to right)
   dir		0: horizontal line (left to right)
 		1: vertical line (top to bottom)
 		1: vertical line (top to bottom)
-  asumption: 
+  assumption: 
     all clipping done
     all clipping done
 */
 */
 
 
@@ -1546,11 +1762,14 @@ void u8g2_SetFontMode(u8g2_t *u8g2, uint8_t is_transparent);
 uint8_t u8g2_IsGlyph(u8g2_t *u8g2, uint16_t requested_encoding);
 uint8_t u8g2_IsGlyph(u8g2_t *u8g2, uint16_t requested_encoding);
 int8_t u8g2_GetGlyphWidth(u8g2_t *u8g2, uint16_t requested_encoding);
 int8_t u8g2_GetGlyphWidth(u8g2_t *u8g2, uint16_t requested_encoding);
 u8g2_uint_t u8g2_DrawGlyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding);
 u8g2_uint_t u8g2_DrawGlyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding);
+u8g2_uint_t u8g2_DrawGlyphX2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding);
 int8_t u8g2_GetStrX(u8g2_t *u8g2, const char *s);	/* for u8g compatibility */
 int8_t u8g2_GetStrX(u8g2_t *u8g2, const char *s);	/* for u8g compatibility */
 
 
 void u8g2_SetFontDirection(u8g2_t *u8g2, uint8_t dir);
 void u8g2_SetFontDirection(u8g2_t *u8g2, uint8_t dir);
 u8g2_uint_t u8g2_DrawStr(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str);
 u8g2_uint_t u8g2_DrawStr(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str);
+u8g2_uint_t u8g2_DrawStrX2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str);
 u8g2_uint_t u8g2_DrawUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str);
 u8g2_uint_t u8g2_DrawUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str);
+u8g2_uint_t u8g2_DrawUTF8X2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str);
 u8g2_uint_t u8g2_DrawExtendedUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, u8g2_kerning_t *kerning, const char *str);
 u8g2_uint_t u8g2_DrawExtendedUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, u8g2_kerning_t *kerning, const char *str);
 u8g2_uint_t u8g2_DrawExtUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, const uint16_t *kerning_table, const char *str);
 u8g2_uint_t u8g2_DrawExtUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, const uint16_t *kerning_table, const char *str);
 
 
@@ -1613,6 +1832,10 @@ void u8g2_SetupBuffer_TGA_LCD(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb);
 /* u8x8_d_bitmap.c */
 /* u8x8_d_bitmap.c */
 void u8g2_SetupBitmap(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb, uint16_t pixel_width, uint16_t pixel_height);
 void u8g2_SetupBitmap(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb, uint16_t pixel_width, uint16_t pixel_height);
 
 
+/*==========================================*/
+/* u8x8_d_framebuffer.c */
+void u8g2_SetupLinuxFb(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb, const char *fb_device);
+
 
 
 /*==========================================*/
 /*==========================================*/
 /* u8x8_d_utf8.c */
 /* u8x8_d_utf8.c */
@@ -1649,11 +1872,18 @@ extern const uint8_t u8g2_font_squeezed_r7_tr[] U8G2_FONT_SECTION("u8g2_font_squ
 extern const uint8_t u8g2_font_squeezed_r7_tn[] U8G2_FONT_SECTION("u8g2_font_squeezed_r7_tn");
 extern const uint8_t u8g2_font_squeezed_r7_tn[] U8G2_FONT_SECTION("u8g2_font_squeezed_r7_tn");
 extern const uint8_t u8g2_font_squeezed_b7_tr[] U8G2_FONT_SECTION("u8g2_font_squeezed_b7_tr");
 extern const uint8_t u8g2_font_squeezed_b7_tr[] U8G2_FONT_SECTION("u8g2_font_squeezed_b7_tr");
 extern const uint8_t u8g2_font_squeezed_b7_tn[] U8G2_FONT_SECTION("u8g2_font_squeezed_b7_tn");
 extern const uint8_t u8g2_font_squeezed_b7_tn[] U8G2_FONT_SECTION("u8g2_font_squeezed_b7_tn");
+extern const uint8_t u8g2_font_percent_circle_25_hn[] U8G2_FONT_SECTION("u8g2_font_percent_circle_25_hn");
 extern const uint8_t u8g2_font_freedoomr10_tu[] U8G2_FONT_SECTION("u8g2_font_freedoomr10_tu");
 extern const uint8_t u8g2_font_freedoomr10_tu[] U8G2_FONT_SECTION("u8g2_font_freedoomr10_tu");
 extern const uint8_t u8g2_font_freedoomr10_mu[] U8G2_FONT_SECTION("u8g2_font_freedoomr10_mu");
 extern const uint8_t u8g2_font_freedoomr10_mu[] U8G2_FONT_SECTION("u8g2_font_freedoomr10_mu");
 extern const uint8_t u8g2_font_freedoomr25_tn[] U8G2_FONT_SECTION("u8g2_font_freedoomr25_tn");
 extern const uint8_t u8g2_font_freedoomr25_tn[] U8G2_FONT_SECTION("u8g2_font_freedoomr25_tn");
 extern const uint8_t u8g2_font_freedoomr25_mn[] U8G2_FONT_SECTION("u8g2_font_freedoomr25_mn");
 extern const uint8_t u8g2_font_freedoomr25_mn[] U8G2_FONT_SECTION("u8g2_font_freedoomr25_mn");
 extern const uint8_t u8g2_font_7Segments_26x42_mn[] U8G2_FONT_SECTION("u8g2_font_7Segments_26x42_mn");
 extern const uint8_t u8g2_font_7Segments_26x42_mn[] U8G2_FONT_SECTION("u8g2_font_7Segments_26x42_mn");
+extern const uint8_t u8g2_font_7_Seg_33x19_mn[] U8G2_FONT_SECTION("u8g2_font_7_Seg_33x19_mn");
+extern const uint8_t u8g2_font_7_Seg_41x21_mn[] U8G2_FONT_SECTION("u8g2_font_7_Seg_41x21_mn");
+extern const uint8_t u8g2_font_tiny5_tf[] U8G2_FONT_SECTION("u8g2_font_tiny5_tf");
+extern const uint8_t u8g2_font_tiny5_tr[] U8G2_FONT_SECTION("u8g2_font_tiny5_tr");
+extern const uint8_t u8g2_font_04b_03b_tr[] U8G2_FONT_SECTION("u8g2_font_04b_03b_tr");
+extern const uint8_t u8g2_font_04b_03_tr[] U8G2_FONT_SECTION("u8g2_font_04b_03_tr");
 extern const uint8_t u8g2_font_amstrad_cpc_extended_8f[] U8G2_FONT_SECTION("u8g2_font_amstrad_cpc_extended_8f");
 extern const uint8_t u8g2_font_amstrad_cpc_extended_8f[] U8G2_FONT_SECTION("u8g2_font_amstrad_cpc_extended_8f");
 extern const uint8_t u8g2_font_amstrad_cpc_extended_8r[] U8G2_FONT_SECTION("u8g2_font_amstrad_cpc_extended_8r");
 extern const uint8_t u8g2_font_amstrad_cpc_extended_8r[] U8G2_FONT_SECTION("u8g2_font_amstrad_cpc_extended_8r");
 extern const uint8_t u8g2_font_amstrad_cpc_extended_8n[] U8G2_FONT_SECTION("u8g2_font_amstrad_cpc_extended_8n");
 extern const uint8_t u8g2_font_amstrad_cpc_extended_8n[] U8G2_FONT_SECTION("u8g2_font_amstrad_cpc_extended_8n");
@@ -1825,6 +2055,7 @@ extern const uint8_t u8g2_font_10x20_t_greek[] U8G2_FONT_SECTION("u8g2_font_10x2
 extern const uint8_t u8g2_font_10x20_t_cyrillic[] U8G2_FONT_SECTION("u8g2_font_10x20_t_cyrillic");
 extern const uint8_t u8g2_font_10x20_t_cyrillic[] U8G2_FONT_SECTION("u8g2_font_10x20_t_cyrillic");
 extern const uint8_t u8g2_font_10x20_t_arabic[] U8G2_FONT_SECTION("u8g2_font_10x20_t_arabic");
 extern const uint8_t u8g2_font_10x20_t_arabic[] U8G2_FONT_SECTION("u8g2_font_10x20_t_arabic");
 extern const uint8_t u8g2_font_siji_t_6x10[] U8G2_FONT_SECTION("u8g2_font_siji_t_6x10");
 extern const uint8_t u8g2_font_siji_t_6x10[] U8G2_FONT_SECTION("u8g2_font_siji_t_6x10");
+extern const uint8_t u8g2_font_waffle_t_all[] U8G2_FONT_SECTION("u8g2_font_waffle_t_all");
 extern const uint8_t u8g2_font_tom_thumb_4x6_t_all[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_t_all");
 extern const uint8_t u8g2_font_tom_thumb_4x6_t_all[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_t_all");
 extern const uint8_t u8g2_font_tom_thumb_4x6_tf[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_tf");
 extern const uint8_t u8g2_font_tom_thumb_4x6_tf[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_tf");
 extern const uint8_t u8g2_font_tom_thumb_4x6_tr[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_tr");
 extern const uint8_t u8g2_font_tom_thumb_4x6_tr[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_tr");
@@ -1834,6 +2065,18 @@ extern const uint8_t u8g2_font_tom_thumb_4x6_mf[] U8G2_FONT_SECTION("u8g2_font_t
 extern const uint8_t u8g2_font_tom_thumb_4x6_mr[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_mr");
 extern const uint8_t u8g2_font_tom_thumb_4x6_mr[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_mr");
 extern const uint8_t u8g2_font_tom_thumb_4x6_mn[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_mn");
 extern const uint8_t u8g2_font_tom_thumb_4x6_mn[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_mn");
 extern const uint8_t u8g2_font_tom_thumb_4x6_me[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_me");
 extern const uint8_t u8g2_font_tom_thumb_4x6_me[] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_me");
+extern const uint8_t u8g2_font_mystery_quest_24_tf[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_24_tf");
+extern const uint8_t u8g2_font_mystery_quest_24_tr[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_24_tr");
+extern const uint8_t u8g2_font_mystery_quest_24_tn[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_24_tn");
+extern const uint8_t u8g2_font_mystery_quest_28_tf[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_28_tf");
+extern const uint8_t u8g2_font_mystery_quest_28_tr[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_28_tr");
+extern const uint8_t u8g2_font_mystery_quest_28_tn[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_28_tn");
+extern const uint8_t u8g2_font_mystery_quest_32_tr[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_32_tr");
+extern const uint8_t u8g2_font_mystery_quest_32_tn[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_32_tn");
+extern const uint8_t u8g2_font_mystery_quest_36_tn[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_36_tn");
+extern const uint8_t u8g2_font_mystery_quest_42_tn[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_42_tn");
+extern const uint8_t u8g2_font_mystery_quest_48_tn[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_48_tn");
+extern const uint8_t u8g2_font_mystery_quest_56_tn[] U8G2_FONT_SECTION("u8g2_font_mystery_quest_56_tn");
 extern const uint8_t u8g2_font_t0_11_tf[] U8G2_FONT_SECTION("u8g2_font_t0_11_tf");
 extern const uint8_t u8g2_font_t0_11_tf[] U8G2_FONT_SECTION("u8g2_font_t0_11_tf");
 extern const uint8_t u8g2_font_t0_11_tr[] U8G2_FONT_SECTION("u8g2_font_t0_11_tr");
 extern const uint8_t u8g2_font_t0_11_tr[] U8G2_FONT_SECTION("u8g2_font_t0_11_tr");
 extern const uint8_t u8g2_font_t0_11_tn[] U8G2_FONT_SECTION("u8g2_font_t0_11_tn");
 extern const uint8_t u8g2_font_t0_11_tn[] U8G2_FONT_SECTION("u8g2_font_t0_11_tn");
@@ -2259,6 +2502,8 @@ extern const uint8_t u8g2_font_secretaryhand_tf[] U8G2_FONT_SECTION("u8g2_font_s
 extern const uint8_t u8g2_font_secretaryhand_tr[] U8G2_FONT_SECTION("u8g2_font_secretaryhand_tr");
 extern const uint8_t u8g2_font_secretaryhand_tr[] U8G2_FONT_SECTION("u8g2_font_secretaryhand_tr");
 extern const uint8_t u8g2_font_secretaryhand_tn[] U8G2_FONT_SECTION("u8g2_font_secretaryhand_tn");
 extern const uint8_t u8g2_font_secretaryhand_tn[] U8G2_FONT_SECTION("u8g2_font_secretaryhand_tn");
 extern const uint8_t u8g2_font_secretaryhand_t_all[] U8G2_FONT_SECTION("u8g2_font_secretaryhand_t_all");
 extern const uint8_t u8g2_font_secretaryhand_t_all[] U8G2_FONT_SECTION("u8g2_font_secretaryhand_t_all");
+extern const uint8_t u8g2_font_garbagecan_tf[] U8G2_FONT_SECTION("u8g2_font_garbagecan_tf");
+extern const uint8_t u8g2_font_garbagecan_tr[] U8G2_FONT_SECTION("u8g2_font_garbagecan_tr");
 extern const uint8_t u8g2_font_beanstalk_mel_tr[] U8G2_FONT_SECTION("u8g2_font_beanstalk_mel_tr");
 extern const uint8_t u8g2_font_beanstalk_mel_tr[] U8G2_FONT_SECTION("u8g2_font_beanstalk_mel_tr");
 extern const uint8_t u8g2_font_beanstalk_mel_tn[] U8G2_FONT_SECTION("u8g2_font_beanstalk_mel_tn");
 extern const uint8_t u8g2_font_beanstalk_mel_tn[] U8G2_FONT_SECTION("u8g2_font_beanstalk_mel_tn");
 extern const uint8_t u8g2_font_cube_mel_tr[] U8G2_FONT_SECTION("u8g2_font_cube_mel_tr");
 extern const uint8_t u8g2_font_cube_mel_tr[] U8G2_FONT_SECTION("u8g2_font_cube_mel_tr");
@@ -2292,6 +2537,8 @@ extern const uint8_t u8g2_font_squirrel_tu[] U8G2_FONT_SECTION("u8g2_font_squirr
 extern const uint8_t u8g2_font_diodesemimono_tr[] U8G2_FONT_SECTION("u8g2_font_diodesemimono_tr");
 extern const uint8_t u8g2_font_diodesemimono_tr[] U8G2_FONT_SECTION("u8g2_font_diodesemimono_tr");
 extern const uint8_t u8g2_font_questgiver_tr[] U8G2_FONT_SECTION("u8g2_font_questgiver_tr");
 extern const uint8_t u8g2_font_questgiver_tr[] U8G2_FONT_SECTION("u8g2_font_questgiver_tr");
 extern const uint8_t u8g2_font_seraphimb1_tr[] U8G2_FONT_SECTION("u8g2_font_seraphimb1_tr");
 extern const uint8_t u8g2_font_seraphimb1_tr[] U8G2_FONT_SECTION("u8g2_font_seraphimb1_tr");
+extern const uint8_t u8g2_font_resoledbold_tr[] U8G2_FONT_SECTION("u8g2_font_resoledbold_tr");
+extern const uint8_t u8g2_font_resoledmedium_tr[] U8G2_FONT_SECTION("u8g2_font_resoledmedium_tr");
 extern const uint8_t u8g2_font_jinxedwizards_tr[] U8G2_FONT_SECTION("u8g2_font_jinxedwizards_tr");
 extern const uint8_t u8g2_font_jinxedwizards_tr[] U8G2_FONT_SECTION("u8g2_font_jinxedwizards_tr");
 extern const uint8_t u8g2_font_lastpriestess_tr[] U8G2_FONT_SECTION("u8g2_font_lastpriestess_tr");
 extern const uint8_t u8g2_font_lastpriestess_tr[] U8G2_FONT_SECTION("u8g2_font_lastpriestess_tr");
 extern const uint8_t u8g2_font_lastpriestess_tu[] U8G2_FONT_SECTION("u8g2_font_lastpriestess_tu");
 extern const uint8_t u8g2_font_lastpriestess_tu[] U8G2_FONT_SECTION("u8g2_font_lastpriestess_tu");
@@ -2324,6 +2571,9 @@ extern const uint8_t u8g2_font_tenthinnerguys_tn[] U8G2_FONT_SECTION("u8g2_font_
 extern const uint8_t u8g2_font_tenthinnerguys_tu[] U8G2_FONT_SECTION("u8g2_font_tenthinnerguys_tu");
 extern const uint8_t u8g2_font_tenthinnerguys_tu[] U8G2_FONT_SECTION("u8g2_font_tenthinnerguys_tu");
 extern const uint8_t u8g2_font_tenthinnerguys_t_all[] U8G2_FONT_SECTION("u8g2_font_tenthinnerguys_t_all");
 extern const uint8_t u8g2_font_tenthinnerguys_t_all[] U8G2_FONT_SECTION("u8g2_font_tenthinnerguys_t_all");
 extern const uint8_t u8g2_font_twelvedings_t_all[] U8G2_FONT_SECTION("u8g2_font_twelvedings_t_all");
 extern const uint8_t u8g2_font_twelvedings_t_all[] U8G2_FONT_SECTION("u8g2_font_twelvedings_t_all");
+extern const uint8_t u8g2_font_frigidaire_mr[] U8G2_FONT_SECTION("u8g2_font_frigidaire_mr");
+extern const uint8_t u8g2_font_lord_mr[] U8G2_FONT_SECTION("u8g2_font_lord_mr");
+extern const uint8_t u8g2_font_abel_mr[] U8G2_FONT_SECTION("u8g2_font_abel_mr");
 extern const uint8_t u8g2_font_fewture_tf[] U8G2_FONT_SECTION("u8g2_font_fewture_tf");
 extern const uint8_t u8g2_font_fewture_tf[] U8G2_FONT_SECTION("u8g2_font_fewture_tf");
 extern const uint8_t u8g2_font_fewture_tr[] U8G2_FONT_SECTION("u8g2_font_fewture_tr");
 extern const uint8_t u8g2_font_fewture_tr[] U8G2_FONT_SECTION("u8g2_font_fewture_tr");
 extern const uint8_t u8g2_font_fewture_tn[] U8G2_FONT_SECTION("u8g2_font_fewture_tn");
 extern const uint8_t u8g2_font_fewture_tn[] U8G2_FONT_SECTION("u8g2_font_fewture_tn");
@@ -2362,9 +2612,104 @@ extern const uint8_t u8g2_font_fancypixels_tf[] U8G2_FONT_SECTION("u8g2_font_fan
 extern const uint8_t u8g2_font_fancypixels_tr[] U8G2_FONT_SECTION("u8g2_font_fancypixels_tr");
 extern const uint8_t u8g2_font_fancypixels_tr[] U8G2_FONT_SECTION("u8g2_font_fancypixels_tr");
 extern const uint8_t u8g2_font_heavybottom_tr[] U8G2_FONT_SECTION("u8g2_font_heavybottom_tr");
 extern const uint8_t u8g2_font_heavybottom_tr[] U8G2_FONT_SECTION("u8g2_font_heavybottom_tr");
 extern const uint8_t u8g2_font_iconquadpix_m_all[] U8G2_FONT_SECTION("u8g2_font_iconquadpix_m_all");
 extern const uint8_t u8g2_font_iconquadpix_m_all[] U8G2_FONT_SECTION("u8g2_font_iconquadpix_m_all");
-extern const uint8_t u8g2_font_lastapprenticebold_tr[] U8G2_FONT_SECTION("u8g2_font_lastapprenticebold_tr");
-extern const uint8_t u8g2_font_lastapprenticethin_tr[] U8G2_FONT_SECTION("u8g2_font_lastapprenticethin_tr");
 extern const uint8_t u8g2_font_tallpix_tr[] U8G2_FONT_SECTION("u8g2_font_tallpix_tr");
 extern const uint8_t u8g2_font_tallpix_tr[] U8G2_FONT_SECTION("u8g2_font_tallpix_tr");
+extern const uint8_t u8g2_font_botmaker_te[] U8G2_FONT_SECTION("u8g2_font_botmaker_te");
+extern const uint8_t u8g2_font_efraneextracondensed_te[] U8G2_FONT_SECTION("u8g2_font_efraneextracondensed_te");
+extern const uint8_t u8g2_font_3x3basic_tr[] U8G2_FONT_SECTION("u8g2_font_3x3basic_tr");
+extern const uint8_t u8g2_font_tiny_gk_tr[] U8G2_FONT_SECTION("u8g2_font_tiny_gk_tr");
+extern const uint8_t u8g2_font_threepix_tr[] U8G2_FONT_SECTION("u8g2_font_threepix_tr");
+extern const uint8_t u8g2_font_eventhrees_tr[] U8G2_FONT_SECTION("u8g2_font_eventhrees_tr");
+extern const uint8_t u8g2_font_fourmat_tf[] U8G2_FONT_SECTION("u8g2_font_fourmat_tf");
+extern const uint8_t u8g2_font_fourmat_tr[] U8G2_FONT_SECTION("u8g2_font_fourmat_tr");
+extern const uint8_t u8g2_font_fourmat_te[] U8G2_FONT_SECTION("u8g2_font_fourmat_te");
+extern const uint8_t u8g2_font_tiny_simon_tr[] U8G2_FONT_SECTION("u8g2_font_tiny_simon_tr");
+extern const uint8_t u8g2_font_tiny_simon_mr[] U8G2_FONT_SECTION("u8g2_font_tiny_simon_mr");
+extern const uint8_t u8g2_font_smolfont_tf[] U8G2_FONT_SECTION("u8g2_font_smolfont_tf");
+extern const uint8_t u8g2_font_smolfont_tr[] U8G2_FONT_SECTION("u8g2_font_smolfont_tr");
+extern const uint8_t u8g2_font_smolfont_te[] U8G2_FONT_SECTION("u8g2_font_smolfont_te");
+extern const uint8_t u8g2_font_tinyunicode_tf[] U8G2_FONT_SECTION("u8g2_font_tinyunicode_tf");
+extern const uint8_t u8g2_font_tinyunicode_tr[] U8G2_FONT_SECTION("u8g2_font_tinyunicode_tr");
+extern const uint8_t u8g2_font_tinyunicode_te[] U8G2_FONT_SECTION("u8g2_font_tinyunicode_te");
+extern const uint8_t u8g2_font_tinypixie2_tr[] U8G2_FONT_SECTION("u8g2_font_tinypixie2_tr");
+extern const uint8_t u8g2_font_standardized3x5_tr[] U8G2_FONT_SECTION("u8g2_font_standardized3x5_tr");
+extern const uint8_t u8g2_font_fivepx_tr[] U8G2_FONT_SECTION("u8g2_font_fivepx_tr");
+extern const uint8_t u8g2_font_3x5im_tr[] U8G2_FONT_SECTION("u8g2_font_3x5im_tr");
+extern const uint8_t u8g2_font_3x5im_te[] U8G2_FONT_SECTION("u8g2_font_3x5im_te");
+extern const uint8_t u8g2_font_3x5im_mr[] U8G2_FONT_SECTION("u8g2_font_3x5im_mr");
+extern const uint8_t u8g2_font_wedge_tr[] U8G2_FONT_SECTION("u8g2_font_wedge_tr");
+extern const uint8_t u8g2_font_kibibyte_tr[] U8G2_FONT_SECTION("u8g2_font_kibibyte_tr");
+extern const uint8_t u8g2_font_kibibyte_te[] U8G2_FONT_SECTION("u8g2_font_kibibyte_te");
+extern const uint8_t u8g2_font_tinyface_tr[] U8G2_FONT_SECTION("u8g2_font_tinyface_tr");
+extern const uint8_t u8g2_font_tinyface_te[] U8G2_FONT_SECTION("u8g2_font_tinyface_te");
+extern const uint8_t u8g2_font_smallsimple_tr[] U8G2_FONT_SECTION("u8g2_font_smallsimple_tr");
+extern const uint8_t u8g2_font_smallsimple_te[] U8G2_FONT_SECTION("u8g2_font_smallsimple_te");
+extern const uint8_t u8g2_font_simple1_tf[] U8G2_FONT_SECTION("u8g2_font_simple1_tf");
+extern const uint8_t u8g2_font_simple1_tr[] U8G2_FONT_SECTION("u8g2_font_simple1_tr");
+extern const uint8_t u8g2_font_simple1_te[] U8G2_FONT_SECTION("u8g2_font_simple1_te");
+extern const uint8_t u8g2_font_likeminecraft_te[] U8G2_FONT_SECTION("u8g2_font_likeminecraft_te");
+extern const uint8_t u8g2_font_medsans_tr[] U8G2_FONT_SECTION("u8g2_font_medsans_tr");
+extern const uint8_t u8g2_font_heisans_tr[] U8G2_FONT_SECTION("u8g2_font_heisans_tr");
+extern const uint8_t u8g2_font_originalsans_tr[] U8G2_FONT_SECTION("u8g2_font_originalsans_tr");
+extern const uint8_t u8g2_font_minicute_tr[] U8G2_FONT_SECTION("u8g2_font_minicute_tr");
+extern const uint8_t u8g2_font_minicute_te[] U8G2_FONT_SECTION("u8g2_font_minicute_te");
+extern const uint8_t u8g2_font_scrum_tf[] U8G2_FONT_SECTION("u8g2_font_scrum_tf");
+extern const uint8_t u8g2_font_scrum_tr[] U8G2_FONT_SECTION("u8g2_font_scrum_tr");
+extern const uint8_t u8g2_font_scrum_te[] U8G2_FONT_SECTION("u8g2_font_scrum_te");
+extern const uint8_t u8g2_font_stylishcharm_tr[] U8G2_FONT_SECTION("u8g2_font_stylishcharm_tr");
+extern const uint8_t u8g2_font_stylishcharm_te[] U8G2_FONT_SECTION("u8g2_font_stylishcharm_te");
+extern const uint8_t u8g2_font_sisterserif_tr[] U8G2_FONT_SECTION("u8g2_font_sisterserif_tr");
+extern const uint8_t u8g2_font_princess_tr[] U8G2_FONT_SECTION("u8g2_font_princess_tr");
+extern const uint8_t u8g2_font_princess_te[] U8G2_FONT_SECTION("u8g2_font_princess_te");
+extern const uint8_t u8g2_font_dystopia_tr[] U8G2_FONT_SECTION("u8g2_font_dystopia_tr");
+extern const uint8_t u8g2_font_dystopia_te[] U8G2_FONT_SECTION("u8g2_font_dystopia_te");
+extern const uint8_t u8g2_font_lastapprenticethin_tr[] U8G2_FONT_SECTION("u8g2_font_lastapprenticethin_tr");
+extern const uint8_t u8g2_font_lastapprenticethin_te[] U8G2_FONT_SECTION("u8g2_font_lastapprenticethin_te");
+extern const uint8_t u8g2_font_lastapprenticebold_tr[] U8G2_FONT_SECTION("u8g2_font_lastapprenticebold_tr");
+extern const uint8_t u8g2_font_lastapprenticebold_te[] U8G2_FONT_SECTION("u8g2_font_lastapprenticebold_te");
+extern const uint8_t u8g2_font_bpixel_tr[] U8G2_FONT_SECTION("u8g2_font_bpixel_tr");
+extern const uint8_t u8g2_font_bpixel_te[] U8G2_FONT_SECTION("u8g2_font_bpixel_te");
+extern const uint8_t u8g2_font_bpixeldouble_tr[] U8G2_FONT_SECTION("u8g2_font_bpixeldouble_tr");
+extern const uint8_t u8g2_font_mildras_tr[] U8G2_FONT_SECTION("u8g2_font_mildras_tr");
+extern const uint8_t u8g2_font_mildras_te[] U8G2_FONT_SECTION("u8g2_font_mildras_te");
+extern const uint8_t u8g2_font_minuteconsole_mr[] U8G2_FONT_SECTION("u8g2_font_minuteconsole_mr");
+extern const uint8_t u8g2_font_minuteconsole_tr[] U8G2_FONT_SECTION("u8g2_font_minuteconsole_tr");
+extern const uint8_t u8g2_font_busdisplay11x5_tr[] U8G2_FONT_SECTION("u8g2_font_busdisplay11x5_tr");
+extern const uint8_t u8g2_font_busdisplay11x5_te[] U8G2_FONT_SECTION("u8g2_font_busdisplay11x5_te");
+extern const uint8_t u8g2_font_busdisplay8x5_tr[] U8G2_FONT_SECTION("u8g2_font_busdisplay8x5_tr");
+extern const uint8_t u8g2_font_sticker100complete_tr[] U8G2_FONT_SECTION("u8g2_font_sticker100complete_tr");
+extern const uint8_t u8g2_font_sticker100complete_te[] U8G2_FONT_SECTION("u8g2_font_sticker100complete_te");
+extern const uint8_t u8g2_font_doomalpha04_tr[] U8G2_FONT_SECTION("u8g2_font_doomalpha04_tr");
+extern const uint8_t u8g2_font_doomalpha04_te[] U8G2_FONT_SECTION("u8g2_font_doomalpha04_te");
+extern const uint8_t u8g2_font_greenbloodserif2_tr[] U8G2_FONT_SECTION("u8g2_font_greenbloodserif2_tr");
+extern const uint8_t u8g2_font_eckpixel_tr[] U8G2_FONT_SECTION("u8g2_font_eckpixel_tr");
+extern const uint8_t u8g2_font_elispe_tr[] U8G2_FONT_SECTION("u8g2_font_elispe_tr");
+extern const uint8_t u8g2_font_neuecraft_tr[] U8G2_FONT_SECTION("u8g2_font_neuecraft_tr");
+extern const uint8_t u8g2_font_neuecraft_te[] U8G2_FONT_SECTION("u8g2_font_neuecraft_te");
+extern const uint8_t u8g2_font_8bitclassic_tf[] U8G2_FONT_SECTION("u8g2_font_8bitclassic_tf");
+extern const uint8_t u8g2_font_8bitclassic_tr[] U8G2_FONT_SECTION("u8g2_font_8bitclassic_tr");
+extern const uint8_t u8g2_font_8bitclassic_te[] U8G2_FONT_SECTION("u8g2_font_8bitclassic_te");
+extern const uint8_t u8g2_font_littlemissloudonbold_tr[] U8G2_FONT_SECTION("u8g2_font_littlemissloudonbold_tr");
+extern const uint8_t u8g2_font_littlemissloudonbold_te[] U8G2_FONT_SECTION("u8g2_font_littlemissloudonbold_te");
+extern const uint8_t u8g2_font_commodore64_tr[] U8G2_FONT_SECTION("u8g2_font_commodore64_tr");
+extern const uint8_t u8g2_font_new3x9pixelfont_tf[] U8G2_FONT_SECTION("u8g2_font_new3x9pixelfont_tf");
+extern const uint8_t u8g2_font_new3x9pixelfont_tr[] U8G2_FONT_SECTION("u8g2_font_new3x9pixelfont_tr");
+extern const uint8_t u8g2_font_new3x9pixelfont_te[] U8G2_FONT_SECTION("u8g2_font_new3x9pixelfont_te");
+extern const uint8_t u8g2_font_sonicmania_tr[] U8G2_FONT_SECTION("u8g2_font_sonicmania_tr");
+extern const uint8_t u8g2_font_sonicmania_te[] U8G2_FONT_SECTION("u8g2_font_sonicmania_te");
+extern const uint8_t u8g2_font_bytesize_tf[] U8G2_FONT_SECTION("u8g2_font_bytesize_tf");
+extern const uint8_t u8g2_font_bytesize_tr[] U8G2_FONT_SECTION("u8g2_font_bytesize_tr");
+extern const uint8_t u8g2_font_bytesize_te[] U8G2_FONT_SECTION("u8g2_font_bytesize_te");
+extern const uint8_t u8g2_font_pixzillav1_tf[] U8G2_FONT_SECTION("u8g2_font_pixzillav1_tf");
+extern const uint8_t u8g2_font_pixzillav1_tr[] U8G2_FONT_SECTION("u8g2_font_pixzillav1_tr");
+extern const uint8_t u8g2_font_pixzillav1_te[] U8G2_FONT_SECTION("u8g2_font_pixzillav1_te");
+extern const uint8_t u8g2_font_ciircle13_tr[] U8G2_FONT_SECTION("u8g2_font_ciircle13_tr");
+extern const uint8_t u8g2_font_pxclassic_tf[] U8G2_FONT_SECTION("u8g2_font_pxclassic_tf");
+extern const uint8_t u8g2_font_pxclassic_tr[] U8G2_FONT_SECTION("u8g2_font_pxclassic_tr");
+extern const uint8_t u8g2_font_pxclassic_te[] U8G2_FONT_SECTION("u8g2_font_pxclassic_te");
+extern const uint8_t u8g2_font_moosenooks_tr[] U8G2_FONT_SECTION("u8g2_font_moosenooks_tr");
+extern const uint8_t u8g2_font_tallpixelextended_tf[] U8G2_FONT_SECTION("u8g2_font_tallpixelextended_tf");
+extern const uint8_t u8g2_font_tallpixelextended_tr[] U8G2_FONT_SECTION("u8g2_font_tallpixelextended_tr");
+extern const uint8_t u8g2_font_tallpixelextended_te[] U8G2_FONT_SECTION("u8g2_font_tallpixelextended_te");
 extern const uint8_t u8g2_font_BBSesque_tf[] U8G2_FONT_SECTION("u8g2_font_BBSesque_tf");
 extern const uint8_t u8g2_font_BBSesque_tf[] U8G2_FONT_SECTION("u8g2_font_BBSesque_tf");
 extern const uint8_t u8g2_font_BBSesque_tr[] U8G2_FONT_SECTION("u8g2_font_BBSesque_tr");
 extern const uint8_t u8g2_font_BBSesque_tr[] U8G2_FONT_SECTION("u8g2_font_BBSesque_tr");
 extern const uint8_t u8g2_font_BBSesque_te[] U8G2_FONT_SECTION("u8g2_font_BBSesque_te");
 extern const uint8_t u8g2_font_BBSesque_te[] U8G2_FONT_SECTION("u8g2_font_BBSesque_te");
@@ -2382,6 +2727,8 @@ extern const uint8_t u8g2_font_ImpactBits_tr[] U8G2_FONT_SECTION("u8g2_font_Impa
 extern const uint8_t u8g2_font_IPAandRUSLCD_tf[] U8G2_FONT_SECTION("u8g2_font_IPAandRUSLCD_tf");
 extern const uint8_t u8g2_font_IPAandRUSLCD_tf[] U8G2_FONT_SECTION("u8g2_font_IPAandRUSLCD_tf");
 extern const uint8_t u8g2_font_IPAandRUSLCD_tr[] U8G2_FONT_SECTION("u8g2_font_IPAandRUSLCD_tr");
 extern const uint8_t u8g2_font_IPAandRUSLCD_tr[] U8G2_FONT_SECTION("u8g2_font_IPAandRUSLCD_tr");
 extern const uint8_t u8g2_font_IPAandRUSLCD_te[] U8G2_FONT_SECTION("u8g2_font_IPAandRUSLCD_te");
 extern const uint8_t u8g2_font_IPAandRUSLCD_te[] U8G2_FONT_SECTION("u8g2_font_IPAandRUSLCD_te");
+extern const uint8_t u8g2_font_PixelTheatre_tr[] U8G2_FONT_SECTION("u8g2_font_PixelTheatre_tr");
+extern const uint8_t u8g2_font_PixelTheatre_te[] U8G2_FONT_SECTION("u8g2_font_PixelTheatre_te");
 extern const uint8_t u8g2_font_HelvetiPixel_tr[] U8G2_FONT_SECTION("u8g2_font_HelvetiPixel_tr");
 extern const uint8_t u8g2_font_HelvetiPixel_tr[] U8G2_FONT_SECTION("u8g2_font_HelvetiPixel_tr");
 extern const uint8_t u8g2_font_TimesNewPixel_tr[] U8G2_FONT_SECTION("u8g2_font_TimesNewPixel_tr");
 extern const uint8_t u8g2_font_TimesNewPixel_tr[] U8G2_FONT_SECTION("u8g2_font_TimesNewPixel_tr");
 extern const uint8_t u8g2_font_BitTypeWriter_tr[] U8G2_FONT_SECTION("u8g2_font_BitTypeWriter_tr");
 extern const uint8_t u8g2_font_BitTypeWriter_tr[] U8G2_FONT_SECTION("u8g2_font_BitTypeWriter_tr");
@@ -2393,6 +2740,56 @@ extern const uint8_t u8g2_font_Wizzard_tr[] U8G2_FONT_SECTION("u8g2_font_Wizzard
 extern const uint8_t u8g2_font_HelvetiPixelOutline_tr[] U8G2_FONT_SECTION("u8g2_font_HelvetiPixelOutline_tr");
 extern const uint8_t u8g2_font_HelvetiPixelOutline_tr[] U8G2_FONT_SECTION("u8g2_font_HelvetiPixelOutline_tr");
 extern const uint8_t u8g2_font_HelvetiPixelOutline_te[] U8G2_FONT_SECTION("u8g2_font_HelvetiPixelOutline_te");
 extern const uint8_t u8g2_font_HelvetiPixelOutline_te[] U8G2_FONT_SECTION("u8g2_font_HelvetiPixelOutline_te");
 extern const uint8_t u8g2_font_Untitled16PixelSansSerifBitmap_tr[] U8G2_FONT_SECTION("u8g2_font_Untitled16PixelSansSerifBitmap_tr");
 extern const uint8_t u8g2_font_Untitled16PixelSansSerifBitmap_tr[] U8G2_FONT_SECTION("u8g2_font_Untitled16PixelSansSerifBitmap_tr");
+extern const uint8_t u8g2_font_UnnamedDOSFontIV_tr[] U8G2_FONT_SECTION("u8g2_font_UnnamedDOSFontIV_tr");
+extern const uint8_t u8g2_font_Terminal_tr[] U8G2_FONT_SECTION("u8g2_font_Terminal_tr");
+extern const uint8_t u8g2_font_Terminal_te[] U8G2_FONT_SECTION("u8g2_font_Terminal_te");
+extern const uint8_t u8g2_font_NokiaLargeBold_tf[] U8G2_FONT_SECTION("u8g2_font_NokiaLargeBold_tf");
+extern const uint8_t u8g2_font_NokiaLargeBold_tr[] U8G2_FONT_SECTION("u8g2_font_NokiaLargeBold_tr");
+extern const uint8_t u8g2_font_NokiaLargeBold_te[] U8G2_FONT_SECTION("u8g2_font_NokiaLargeBold_te");
+extern const uint8_t u8g2_font_NokiaSmallBold_tf[] U8G2_FONT_SECTION("u8g2_font_NokiaSmallBold_tf");
+extern const uint8_t u8g2_font_NokiaSmallBold_tr[] U8G2_FONT_SECTION("u8g2_font_NokiaSmallBold_tr");
+extern const uint8_t u8g2_font_NokiaSmallBold_te[] U8G2_FONT_SECTION("u8g2_font_NokiaSmallBold_te");
+extern const uint8_t u8g2_font_NokiaSmallPlain_tf[] U8G2_FONT_SECTION("u8g2_font_NokiaSmallPlain_tf");
+extern const uint8_t u8g2_font_NokiaSmallPlain_tr[] U8G2_FONT_SECTION("u8g2_font_NokiaSmallPlain_tr");
+extern const uint8_t u8g2_font_NokiaSmallPlain_te[] U8G2_FONT_SECTION("u8g2_font_NokiaSmallPlain_te");
+extern const uint8_t u8g2_font_12x6LED_tf[] U8G2_FONT_SECTION("u8g2_font_12x6LED_tf");
+extern const uint8_t u8g2_font_12x6LED_tr[] U8G2_FONT_SECTION("u8g2_font_12x6LED_tr");
+extern const uint8_t u8g2_font_12x6LED_mn[] U8G2_FONT_SECTION("u8g2_font_12x6LED_mn");
+extern const uint8_t u8g2_font_9x6LED_tf[] U8G2_FONT_SECTION("u8g2_font_9x6LED_tf");
+extern const uint8_t u8g2_font_9x6LED_tr[] U8G2_FONT_SECTION("u8g2_font_9x6LED_tr");
+extern const uint8_t u8g2_font_9x6LED_mn[] U8G2_FONT_SECTION("u8g2_font_9x6LED_mn");
+extern const uint8_t u8g2_font_calblk36_tr[] U8G2_FONT_SECTION("u8g2_font_calblk36_tr");
+extern const uint8_t u8g2_font_callite24_tr[] U8G2_FONT_SECTION("u8g2_font_callite24_tr");
+extern const uint8_t u8g2_font_spleen5x8_mf[] U8G2_FONT_SECTION("u8g2_font_spleen5x8_mf");
+extern const uint8_t u8g2_font_spleen5x8_mr[] U8G2_FONT_SECTION("u8g2_font_spleen5x8_mr");
+extern const uint8_t u8g2_font_spleen5x8_mn[] U8G2_FONT_SECTION("u8g2_font_spleen5x8_mn");
+extern const uint8_t u8g2_font_spleen5x8_mu[] U8G2_FONT_SECTION("u8g2_font_spleen5x8_mu");
+extern const uint8_t u8g2_font_spleen5x8_me[] U8G2_FONT_SECTION("u8g2_font_spleen5x8_me");
+extern const uint8_t u8g2_font_spleen6x12_mf[] U8G2_FONT_SECTION("u8g2_font_spleen6x12_mf");
+extern const uint8_t u8g2_font_spleen6x12_mr[] U8G2_FONT_SECTION("u8g2_font_spleen6x12_mr");
+extern const uint8_t u8g2_font_spleen6x12_mn[] U8G2_FONT_SECTION("u8g2_font_spleen6x12_mn");
+extern const uint8_t u8g2_font_spleen6x12_mu[] U8G2_FONT_SECTION("u8g2_font_spleen6x12_mu");
+extern const uint8_t u8g2_font_spleen6x12_me[] U8G2_FONT_SECTION("u8g2_font_spleen6x12_me");
+extern const uint8_t u8g2_font_spleen8x16_mf[] U8G2_FONT_SECTION("u8g2_font_spleen8x16_mf");
+extern const uint8_t u8g2_font_spleen8x16_mr[] U8G2_FONT_SECTION("u8g2_font_spleen8x16_mr");
+extern const uint8_t u8g2_font_spleen8x16_mn[] U8G2_FONT_SECTION("u8g2_font_spleen8x16_mn");
+extern const uint8_t u8g2_font_spleen8x16_mu[] U8G2_FONT_SECTION("u8g2_font_spleen8x16_mu");
+extern const uint8_t u8g2_font_spleen8x16_me[] U8G2_FONT_SECTION("u8g2_font_spleen8x16_me");
+extern const uint8_t u8g2_font_spleen12x24_mf[] U8G2_FONT_SECTION("u8g2_font_spleen12x24_mf");
+extern const uint8_t u8g2_font_spleen12x24_mr[] U8G2_FONT_SECTION("u8g2_font_spleen12x24_mr");
+extern const uint8_t u8g2_font_spleen12x24_mn[] U8G2_FONT_SECTION("u8g2_font_spleen12x24_mn");
+extern const uint8_t u8g2_font_spleen12x24_mu[] U8G2_FONT_SECTION("u8g2_font_spleen12x24_mu");
+extern const uint8_t u8g2_font_spleen12x24_me[] U8G2_FONT_SECTION("u8g2_font_spleen12x24_me");
+extern const uint8_t u8g2_font_spleen16x32_mf[] U8G2_FONT_SECTION("u8g2_font_spleen16x32_mf");
+extern const uint8_t u8g2_font_spleen16x32_mr[] U8G2_FONT_SECTION("u8g2_font_spleen16x32_mr");
+extern const uint8_t u8g2_font_spleen16x32_mn[] U8G2_FONT_SECTION("u8g2_font_spleen16x32_mn");
+extern const uint8_t u8g2_font_spleen16x32_mu[] U8G2_FONT_SECTION("u8g2_font_spleen16x32_mu");
+extern const uint8_t u8g2_font_spleen16x32_me[] U8G2_FONT_SECTION("u8g2_font_spleen16x32_me");
+extern const uint8_t u8g2_font_spleen32x64_mf[] U8G2_FONT_SECTION("u8g2_font_spleen32x64_mf");
+extern const uint8_t u8g2_font_spleen32x64_mr[] U8G2_FONT_SECTION("u8g2_font_spleen32x64_mr");
+extern const uint8_t u8g2_font_spleen32x64_mn[] U8G2_FONT_SECTION("u8g2_font_spleen32x64_mn");
+extern const uint8_t u8g2_font_spleen32x64_mu[] U8G2_FONT_SECTION("u8g2_font_spleen32x64_mu");
+extern const uint8_t u8g2_font_spleen32x64_me[] U8G2_FONT_SECTION("u8g2_font_spleen32x64_me");
 extern const uint8_t u8g2_font_nokiafc22_tf[] U8G2_FONT_SECTION("u8g2_font_nokiafc22_tf");
 extern const uint8_t u8g2_font_nokiafc22_tf[] U8G2_FONT_SECTION("u8g2_font_nokiafc22_tf");
 extern const uint8_t u8g2_font_nokiafc22_tr[] U8G2_FONT_SECTION("u8g2_font_nokiafc22_tr");
 extern const uint8_t u8g2_font_nokiafc22_tr[] U8G2_FONT_SECTION("u8g2_font_nokiafc22_tr");
 extern const uint8_t u8g2_font_nokiafc22_tn[] U8G2_FONT_SECTION("u8g2_font_nokiafc22_tn");
 extern const uint8_t u8g2_font_nokiafc22_tn[] U8G2_FONT_SECTION("u8g2_font_nokiafc22_tn");

File diff suppressed because it is too large
+ 198 - 162
components/u8g2/u8g2_d_memory.c


File diff suppressed because it is too large
+ 771 - 43
components/u8g2/u8g2_d_setup.c


+ 210 - 2
components/u8g2/u8g2_font.c

@@ -477,11 +477,104 @@ void u8g2_font_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground)
   }
   }
   lx += cnt;
   lx += cnt;
   
   
+  decode->x = lx;
+  decode->y = ly;  
+}
+
+
+void u8g2_font_2x_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground)
+{
+  uint8_t cnt;	/* total number of remaining pixels, which have to be drawn */
+  uint8_t rem; 	/* remaining pixel to the right edge of the glyph */
+  uint8_t current;	/* number of pixels, which need to be drawn for the draw procedure */
+    /* current is either equal to cnt or equal to rem */
+  
+  /* local coordinates of the glyph */
+  uint8_t lx,ly;
+  
+  /* target position on the screen */
+  u8g2_uint_t x, y;
+  
+  u8g2_font_decode_t *decode = &(u8g2->font_decode);
+  
+  cnt = len;
+  
+  /* get the local position */
+  lx = decode->x;
+  ly = decode->y;
+  
+  for(;;)
+  {
+    /* calculate the number of pixel to the right edge of the glyph */
+    rem = decode->glyph_width;
+    rem -= lx;
+    
+    /* calculate how many pixel to draw. This is either to the right edge */
+    /* or lesser, if not enough pixel are left */
+    current = rem;
+    if ( cnt < rem )
+      current = cnt;
+    
+    
+    /* now draw the line, but apply the rotation around the glyph target position */
+    //u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground);
+
+    /* get target position */
+    x = decode->target_x;
+    y = decode->target_y;
+
+    x += lx*2;
+    y += ly*2;
+    
+    /* draw foreground and background (if required) */
+    if ( is_foreground )
+    {
+      u8g2->draw_color = decode->fg_color;			/* draw_color will be restored later */
+      u8g2_DrawHVLine(u8g2, 
+	x, 
+	y, 
+	current*2, 
+	0
+      );
+      u8g2_DrawHVLine(u8g2, 
+	x, 
+	y+1, 
+	current*2, 
+	0
+      );
+    }
+    else if ( decode->is_transparent == 0 )    
+    {
+      u8g2->draw_color = decode->bg_color;			/* draw_color will be restored later */
+      u8g2_DrawHVLine(u8g2, 
+	x, 
+	y, 
+	current*2, 
+	0
+      );   
+      u8g2_DrawHVLine(u8g2, 
+	x, 
+	y+1, 
+	current*2, 
+	0
+      );   
+    }
+    
+    /* check, whether the end of the run length code has been reached */
+    if ( cnt < rem )
+      break;
+    cnt -= rem;
+    lx = 0;
+    ly++;
+  }
+  lx += cnt;
+  
   decode->x = lx;
   decode->x = lx;
   decode->y = ly;
   decode->y = ly;
   
   
 }
 }
 
 
+
 static void u8g2_font_setup_decode(u8g2_t *u8g2, const uint8_t *glyph_data)
 static void u8g2_font_setup_decode(u8g2_t *u8g2, const uint8_t *glyph_data)
 {
 {
   u8g2_font_decode_t *decode = &(u8g2->font_decode);
   u8g2_font_decode_t *decode = &(u8g2->font_decode);
@@ -616,6 +709,68 @@ int8_t u8g2_font_decode_glyph(u8g2_t *u8g2, const uint8_t *glyph_data)
   return d;
   return d;
 }
 }
 
 
+
+int8_t u8g2_font_2x_decode_glyph(u8g2_t *u8g2, const uint8_t *glyph_data)
+{
+  uint8_t a, b;
+  int8_t x, y;
+  int8_t d;
+  int8_t h;
+  u8g2_font_decode_t *decode = &(u8g2->font_decode);
+    
+  u8g2_font_setup_decode(u8g2, glyph_data);     /* set values in u8g2->font_decode data structure */
+  h = u8g2->font_decode.glyph_height;
+  
+  x = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_x);
+  y = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_y);
+  d = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_delta_x);
+  
+  if ( decode->glyph_width > 0 )
+  {
+    decode->target_x += x;
+    decode->target_y -= 2*h+y;
+
+#ifdef U8G2_WITH_INTERSECTION
+    {
+      u8g2_uint_t x0, x1, y0, y1;
+      x0 = decode->target_x;
+      y0 = decode->target_y;
+      x1 = x0;
+      y1 = y0;
+      
+      x1 += 2*decode->glyph_width;
+      y1 += 2*h;      
+      
+      if ( u8g2_IsIntersection(u8g2, x0, y0, x1, y1) == 0 ) 
+	return 2*d;
+    }
+#endif /* U8G2_WITH_INTERSECTION */
+   
+    /* reset local x/y position */
+    decode->x = 0;
+    decode->y = 0;
+    
+    /* decode glyph */
+    for(;;)
+    {
+      a = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_0);
+      b = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_1);
+      do
+      {
+	u8g2_font_2x_decode_len(u8g2, a, 0);
+	u8g2_font_2x_decode_len(u8g2, b, 1);
+      } while( u8g2_font_decode_get_unsigned_bits(decode, 1) != 0 );
+
+      if ( decode->y >= h )
+	break;
+    }
+    
+    /* restore the u8g2 draw color, because this is modified by the decode algo */
+    u8g2->draw_color = decode->fg_color;
+  }
+  return d*2;
+}
+
 /*
 /*
   Description:
   Description:
     Find the starting point of the glyph data.
     Find the starting point of the glyph data.
@@ -726,6 +881,19 @@ static u8g2_uint_t u8g2_font_draw_glyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t
   return dx;
   return dx;
 }
 }
 
 
+static u8g2_uint_t u8g2_font_2x_draw_glyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)
+{
+  u8g2_uint_t dx = 0;
+  u8g2->font_decode.target_x = x;
+  u8g2->font_decode.target_y = y;
+  const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, encoding);
+  if ( glyph_data != NULL )
+  {
+    dx = u8g2_font_2x_decode_glyph(u8g2, glyph_data);
+  }
+  return dx;
+}
+
 
 
 
 
 uint8_t u8g2_IsGlyph(u8g2_t *u8g2, uint16_t requested_encoding)
 uint8_t u8g2_IsGlyph(u8g2_t *u8g2, uint16_t requested_encoding)
@@ -789,6 +957,12 @@ u8g2_uint_t u8g2_DrawGlyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t
   return u8g2_font_draw_glyph(u8g2, x, y, encoding);
   return u8g2_font_draw_glyph(u8g2, x, y, encoding);
 }
 }
 
 
+u8g2_uint_t u8g2_DrawGlyphX2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)
+{
+  y += 2*u8g2->font_calc_vref(u8g2);
+  return u8g2_font_2x_draw_glyph(u8g2, x, y, encoding);
+}
+
 static u8g2_uint_t u8g2_draw_string(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str) U8G2_NOINLINE;
 static u8g2_uint_t u8g2_draw_string(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str) U8G2_NOINLINE;
 static u8g2_uint_t u8g2_draw_string(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
 static u8g2_uint_t u8g2_draw_string(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
 {
 {
@@ -839,12 +1013,41 @@ static u8g2_uint_t u8g2_draw_string(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y,
   return sum;
   return sum;
 }
 }
 
 
+static u8g2_uint_t u8g2_draw_string_2x(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str) U8G2_NOINLINE;
+static u8g2_uint_t u8g2_draw_string_2x(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
+{
+  uint16_t e;
+  u8g2_uint_t delta, sum;
+  u8x8_utf8_init(u8g2_GetU8x8(u8g2));
+  sum = 0;
+  for(;;)
+  {
+    e = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
+    if ( e == 0x0ffff )
+      break;
+    str++;
+    if ( e != 0x0fffe )
+    {
+      delta = u8g2_DrawGlyphX2(u8g2, x, y, e);
+      x += delta;
+      sum += delta;    
+    }
+  }
+  return sum;
+}
+
 u8g2_uint_t u8g2_DrawStr(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
 u8g2_uint_t u8g2_DrawStr(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
 {
 {
   u8g2->u8x8.next_cb = u8x8_ascii_next;
   u8g2->u8x8.next_cb = u8x8_ascii_next;
   return u8g2_draw_string(u8g2, x, y, str);
   return u8g2_draw_string(u8g2, x, y, str);
 }
 }
 
 
+u8g2_uint_t u8g2_DrawStrX2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
+{
+  u8g2->u8x8.next_cb = u8x8_ascii_next;
+  return u8g2_draw_string_2x(u8g2, x, y, str);
+}
+
 /*
 /*
 source: https://en.wikipedia.org/wiki/UTF-8
 source: https://en.wikipedia.org/wiki/UTF-8
 Bits	from 		to			bytes	Byte 1 		Byte 2 		Byte 3 		Byte 4 		Byte 5 		Byte 6
 Bits	from 		to			bytes	Byte 1 		Byte 2 		Byte 3 		Byte 4 		Byte 5 		Byte 6
@@ -861,6 +1064,11 @@ u8g2_uint_t u8g2_DrawUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char
   return u8g2_draw_string(u8g2, x, y, str);
   return u8g2_draw_string(u8g2, x, y, str);
 }
 }
 
 
+u8g2_uint_t u8g2_DrawUTF8X2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
+{
+  u8g2->u8x8.next_cb = u8x8_utf8_next;
+  return u8g2_draw_string_2x(u8g2, x, y, str);
+}
 
 
 
 
 u8g2_uint_t u8g2_DrawExtendedUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, u8g2_kerning_t *kerning, const char *str)
 u8g2_uint_t u8g2_DrawExtendedUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, u8g2_kerning_t *kerning, const char *str)
@@ -1185,9 +1393,9 @@ static void u8g2_GetGlyphHorizontalProperties(u8g2_t *u8g2, uint16_t requested_e
 /* u8g compatible GetStrX function */
 /* u8g compatible GetStrX function */
 int8_t u8g2_GetStrX(u8g2_t *u8g2, const char *s)
 int8_t u8g2_GetStrX(u8g2_t *u8g2, const char *s)
 {
 {
-  uint8_t w = 0;
+  uint8_t w;
+  int8_t dx;
   int8_t ox = 0;
   int8_t ox = 0;
-  int8_t dx = 0;
   u8g2_GetGlyphHorizontalProperties(u8g2, *s, &w, &ox, &dx);
   u8g2_GetGlyphHorizontalProperties(u8g2, *s, &w, &ox, &dx);
   return ox;
   return ox;
 }
 }

File diff suppressed because it is too large
+ 646 - 422
components/u8g2/u8g2_fonts.c


+ 1 - 1
components/u8g2/u8g2_line.c

@@ -81,7 +81,7 @@ void u8g2_DrawLine(u8g2_t *u8g2, u8g2_uint_t x1, u8g2_uint_t y1, u8g2_uint_t x2,
       u8g2_DrawPixel(u8g2, x, y); 
       u8g2_DrawPixel(u8g2, x, y); 
     else 
     else 
       u8g2_DrawPixel(u8g2, y, x); 
       u8g2_DrawPixel(u8g2, y, x); 
-    err -= (uint8_t)dy;
+    err -= (u8g2_uint_t)dy;
     if ( err < 0 ) 
     if ( err < 0 ) 
     {
     {
       y += (u8g2_uint_t)ystep;
       y += (u8g2_uint_t)ystep;

+ 5 - 5
components/u8g2/u8g2_polygon.c

@@ -216,17 +216,17 @@ static void pg_hline(pg_struct *pg, u8g2_t *u8g2)
   
   
   if ( y < 0 )
   if ( y < 0 )
     return;
     return;
-  if ( y >= u8g2_GetDisplayHeight(u8g2) )  // does not work for 256x64 display???
+  if ( y >= (pg_word_t)u8g2_GetDisplayHeight(u8g2) )  // does not work for 256x64 display???
     return;
     return;
   if ( x1 < x2 )
   if ( x1 < x2 )
   {
   {
     if ( x2 < 0 )
     if ( x2 < 0 )
       return;
       return;
-    if ( x1 >= u8g2_GetDisplayWidth(u8g2) )
+    if ( x1 >= (pg_word_t)u8g2_GetDisplayWidth(u8g2) )
       return;
       return;
     if ( x1 < 0 )
     if ( x1 < 0 )
       x1 = 0;
       x1 = 0;
-    if ( x2 >= u8g2_GetDisplayWidth(u8g2) )
+    if ( x2 >= (pg_word_t)u8g2_GetDisplayWidth(u8g2) )
       x2 = u8g2_GetDisplayWidth(u8g2);
       x2 = u8g2_GetDisplayWidth(u8g2);
     u8g2_DrawHLine(u8g2, x1, y, x2 - x1);
     u8g2_DrawHLine(u8g2, x1, y, x2 - x1);
   }
   }
@@ -234,11 +234,11 @@ static void pg_hline(pg_struct *pg, u8g2_t *u8g2)
   {
   {
     if ( x1 < 0 )
     if ( x1 < 0 )
       return;
       return;
-    if ( x2 >= u8g2_GetDisplayWidth(u8g2) )
+    if ( x2 >= (pg_word_t)u8g2_GetDisplayWidth(u8g2) )
       return;
       return;
     if ( x2 < 0 )
     if ( x2 < 0 )
       x1 = 0;
       x1 = 0;
-    if ( x1 >= u8g2_GetDisplayWidth(u8g2) )
+    if ( x1 >= (pg_word_t)u8g2_GetDisplayWidth(u8g2) )
       x1 = u8g2_GetDisplayWidth(u8g2);
       x1 = u8g2_GetDisplayWidth(u8g2);
     u8g2_DrawHLine(u8g2, x2, y, x1 - x2);
     u8g2_DrawHLine(u8g2, x2, y, x1 - x2);
   }
   }

+ 2 - 1
components/u8g2/u8g2_setup.c

@@ -85,6 +85,7 @@ void u8g2_SetupBuffer(u8g2_t *u8g2, uint8_t *buf, uint8_t tile_buf_height, u8g2_
   u8g2->font_decode.is_transparent = 0; /* issue 443 */
   u8g2->font_decode.is_transparent = 0; /* issue 443 */
   u8g2->bitmap_transparency = 0;
   u8g2->bitmap_transparency = 0;
   
   
+  u8g2->font_height_mode = 0; /* issue 2046 */
   u8g2->draw_color = 1;
   u8g2->draw_color = 1;
   u8g2->is_auto_page_clear = 1;
   u8g2->is_auto_page_clear = 1;
   
   
@@ -465,4 +466,4 @@ void u8g2_Setup_null(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_c
 
 
 
 
   
   
-  
+  

+ 60 - 20
components/u8g2/u8x8.h

@@ -4,7 +4,7 @@
   
   
   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 
 
-  Copyright (c) 2016, olikraus@gmail.com
+  Copyright (c) 2016, olikraus@gmail.  
   All rights reserved.
   All rights reserved.
 
 
   Redistribution and use in source and binary forms, with or without modification, 
   Redistribution and use in source and binary forms, with or without modification, 
@@ -34,11 +34,11 @@
   
   
   
   
   U8glib has several layers. Each layer is implemented with a callback function. 
   U8glib has several layers. Each layer is implemented with a callback function. 
-  This callback function handels the messages for the layer.
+  This callback function handles the messages for the layer.
 
 
   The topmost level is the display layer. It includes the following messages:
   The topmost level is the display layer. It includes the following messages:
   
   
-    U8X8_MSG_DISPLAY_SETUP_MEMORY			no communicaation with the display, setup memory ony
+    U8X8_MSG_DISPLAY_SETUP_MEMORY			no communication with the display, setup memory only
     U8X8_MSG_DISPLAY_INIT
     U8X8_MSG_DISPLAY_INIT
     U8X8_MSG_DISPLAY_SET_FLIP_MODE
     U8X8_MSG_DISPLAY_SET_FLIP_MODE
     U8X8_MSG_DISPLAY_SET_POWER_SAVE
     U8X8_MSG_DISPLAY_SET_POWER_SAVE
@@ -94,7 +94,7 @@
 #endif
 #endif
 
 
 /* Define this for an additional user pointer inside the u8x8 data struct */
 /* Define this for an additional user pointer inside the u8x8 data struct */
-//#define U8X8_WITH_USER_PTR
+#define U8X8_WITH_USER_PTR
 
 
 
 
 /* Undefine this to remove u8x8_SetFlipMode function */
 /* Undefine this to remove u8x8_SetFlipMode function */
@@ -102,7 +102,7 @@
 //#define U8X8_WITH_SET_FLIP_MODE
 //#define U8X8_WITH_SET_FLIP_MODE
 
 
 /* Select 0 or 1 for the default flip mode. This is not affected by U8X8_WITH_FLIP_MODE */
 /* Select 0 or 1 for the default flip mode. This is not affected by U8X8_WITH_FLIP_MODE */
-/* Note: Not all display types support a mirror functon for the frame buffer */
+/* Note: Not all display types support a mirror function for the frame buffer */
 /* 26 May 2016: Obsolete */
 /* 26 May 2016: Obsolete */
 //#define U8X8_DEFAULT_FLIP_MODE 0
 //#define U8X8_DEFAULT_FLIP_MODE 0
 
 
@@ -352,7 +352,7 @@ struct u8x8_struct
   uint16_t encoding;		/* encoding result for utf8 decoder in next_cb */
   uint16_t encoding;		/* encoding result for utf8 decoder in next_cb */
   uint8_t x_offset;	/* copied from info struct, can be modified in flip mode */
   uint8_t x_offset;	/* copied from info struct, can be modified in flip mode */
   uint8_t is_font_inverse_mode; 	/* 0: normal, 1: font glyphs are inverted */
   uint8_t is_font_inverse_mode; 	/* 0: normal, 1: font glyphs are inverted */
-  uint8_t i2c_address;	/* a valid i2c adr. Initially this is 255, but this is set to something usefull during DISPLAY_INIT */
+  uint8_t i2c_address;	/* a valid i2c adr. Initially this is 255, but this is set to something useful during DISPLAY_INIT */
 					/* i2c_address is the address for writing data to the display */
 					/* i2c_address is the address for writing data to the display */
 					/* usually, the lowest bit must be zero for a valid address */
 					/* usually, the lowest bit must be zero for a valid address */
   uint8_t i2c_started;	/* for i2c interface */
   uint8_t i2c_started;	/* for i2c interface */
@@ -367,7 +367,7 @@ struct u8x8_struct
   void *user_ptr;
   void *user_ptr;
 #endif
 #endif
 #ifdef U8X8_USE_PINS 
 #ifdef U8X8_USE_PINS 
-  uint8_t pins[U8X8_PIN_CNT];	/* defines a pinlist: Mainly a list of pins for the Arduino Envionment, use U8X8_PIN_xxx to access */
+  uint8_t pins[U8X8_PIN_CNT];	/* defines a pinlist: Mainly a list of pins for the Arduino Environment, use U8X8_PIN_xxx to access */
 #endif
 #endif
 };
 };
 
 
@@ -416,7 +416,7 @@ struct u8log_struct
   void *aux_data;		/* pointer to u8x8 or u8g2 */
   void *aux_data;		/* pointer to u8x8 or u8g2 */
   uint8_t width, height;	/* size of the terminal */
   uint8_t width, height;	/* size of the terminal */
   u8log_cb cb;			/* callback redraw function */
   u8log_cb cb;			/* callback redraw function */
-  uint8_t *screen_buffer;	/* size must be width*heigh bytes */
+  uint8_t *screen_buffer;	/* size must be width*height bytes */
   uint8_t is_redraw_line_for_each_char;
   uint8_t is_redraw_line_for_each_char;
   int8_t line_height_offset;		/* extra offset for the line height (u8g2 only) */
   int8_t line_height_offset;		/* extra offset for the line height (u8g2 only) */
   
   
@@ -477,7 +477,7 @@ void u8x8_d_helper_display_init(u8x8_t *u8g2);
   Name: 	U8X8_MSG_DISPLAY_SET_FLIP_MODE
   Name: 	U8X8_MSG_DISPLAY_SET_FLIP_MODE
   Args:	arg_int: 0: normal mode, 1: flipped HW screen (180 degree)
   Args:	arg_int: 0: normal mode, 1: flipped HW screen (180 degree)
   Tasks:
   Tasks:
-    Reprogramms the display controller to rotate the display by 
+    Reprograms the display controller to rotate the display by 
     180 degree (arg_int = 1) or not (arg_int = 0)
     180 degree (arg_int = 1) or not (arg_int = 0)
     This may change u8g2->x_offset if the display is smaller than the controller ram
     This may change u8g2->x_offset if the display is smaller than the controller ram
     This message should only be supported if U8X8_WITH_FLIP_MODE is defined.
     This message should only be supported if U8X8_WITH_FLIP_MODE is defined.
@@ -639,6 +639,7 @@ void u8x8_SendF(u8x8_t * u8x8, const char *fmt, ...);
 #define U8X8_A(a0)				(U8X8_MSG_CAD_SEND_ARG), (a0)
 #define U8X8_A(a0)				(U8X8_MSG_CAD_SEND_ARG), (a0)
 #define U8X8_CA(c0,a0)			(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0)
 #define U8X8_CA(c0,a0)			(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0)
 #define U8X8_CAA(c0,a0,a1)		(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1)
 #define U8X8_CAA(c0,a0,a1)		(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1)
+#define U8X8_CCAA(c0,c1,a0, a1)	(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_CMD), (c1), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1)
 #define U8X8_CAAA(c0,a0,a1, a2)	(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1), (U8X8_MSG_CAD_SEND_ARG), (a2)
 #define U8X8_CAAA(c0,a0,a1, a2)	(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1), (U8X8_MSG_CAD_SEND_ARG), (a2)
 #define U8X8_CAAAA(c0,a0,a1,a2,a3)		(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1), (U8X8_MSG_CAD_SEND_ARG), (a2), (U8X8_MSG_CAD_SEND_ARG), (a3)
 #define U8X8_CAAAA(c0,a0,a1,a2,a3)		(U8X8_MSG_CAD_SEND_CMD), (c0), (U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1), (U8X8_MSG_CAD_SEND_ARG), (a2), (U8X8_MSG_CAD_SEND_ARG), (a3)
 #define U8X8_AAC(a0,a1,c0)		(U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1), (U8X8_MSG_CAD_SEND_CMD), (c0)
 #define U8X8_AAC(a0,a1,c0)		(U8X8_MSG_CAD_SEND_ARG), (a0), (U8X8_MSG_CAD_SEND_ARG), (a1), (U8X8_MSG_CAD_SEND_CMD), (c0)
@@ -814,6 +815,11 @@ void u8x8_SaveBitmapTGA(u8x8_t *u8x8, const char *filename);
 void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t pixel_width, uint16_t pixel_height);
 void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t pixel_width, uint16_t pixel_height);
 uint8_t u8x8_ConnectBitmapToU8x8(u8x8_t *u8x8);
 uint8_t u8x8_ConnectBitmapToU8x8(u8x8_t *u8x8);
 
 
+/*==========================================*/
+/* u8x8_d_framebuffer.c */
+void u8x8_SetupLinuxFb(u8x8_t *u8x8, int fbfd);
+void u8x8_LinuxFbSetActiveColor(uint32_t color);
+
 /*==========================================*/
 /*==========================================*/
 /* u8x8_d_utf8.c */
 /* u8x8_d_utf8.c */
 void u8x8_Setup_Utf8(u8x8_t *u8x8);	/* stdout UTF-8 display */
 void u8x8_Setup_Utf8(u8x8_t *u8x8);	/* stdout UTF-8 display */
@@ -830,6 +836,7 @@ uint8_t u8x8_d_uc1701_ea_dogs102(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, voi
 uint8_t u8x8_d_uc1701_mini12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1701_mini12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1305_128x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1305_128x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1305_128x32_adafruit(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1305_128x32_adafruit(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+/*uint8_t u8x8_d_ssd1305_128x32_waveshare(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);*/
 uint8_t u8x8_d_ssd1305_128x64_adafruit(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1305_128x64_adafruit(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1305_128x64_raystar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1305_128x64_raystar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -837,6 +844,19 @@ uint8_t u8x8_d_ssd1306_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
 uint8_t u8x8_d_ssd1306_128x64_alt0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1306_128x64_alt0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1309_128x64_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1309_128x64_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1309_128x64_noname2(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1309_128x64_noname2(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1312_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_2040x16(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_128x32_univision(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_128x32_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_102x64_ea_oleds102(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);  /* u8x8_ssd1309.c */
+uint8_t u8x8_d_ssd1306_64x48_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_48x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_64x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_64x32_1f(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_96x16_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_96x40(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_96x39(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1306_72x40_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1106_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1106_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1106_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1106_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1106_128x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1106_128x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -849,21 +869,16 @@ uint8_t u8x8_d_sh1107_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
 uint8_t u8x8_d_sh1107_128x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1107_128x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1107_pimoroni_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1107_pimoroni_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1107_seeed_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1107_seeed_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_sh1107_hjr_oel1m0201_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_sh1107_tk078f288_80x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_sh1108_128x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1108_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1108_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1122_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sh1122_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_st7920_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7920_144x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7920_160x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7920_192x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7920_192x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7920_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7920_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7920_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_2040x16(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_128x32_univision(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_128x32_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_102x64_ea_oleds102(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);  /* u8x8_ssd1309.c */
-uint8_t u8x8_d_ssd1306_64x48_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_48x64_winstar(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_64x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_64x32_1f(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_96x16_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_d_ssd1306_72x40_er(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ls013b7dh03_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ls013b7dh03_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ls027b7dh01_400x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ls027b7dh01_400x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ls027b7dh01_m0_400x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ls027b7dh01_m0_400x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -871,6 +886,7 @@ uint8_t u8x8_d_ls013b7dh05_144x168(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, v
 uint8_t u8x8_d_st7511_avd_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7511_avd_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7528_nhd_c160100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7528_nhd_c160100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7528_erc16064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7528_erc16064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7539_192x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7565_ea_dogm128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7565_ea_dogm128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7565_lm6063(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7565_lm6063(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7565_64128n(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7565_64128n(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -886,16 +902,21 @@ uint8_t u8x8_d_st7565_erc12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
 uint8_t u8x8_d_st7565_erc12864_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);  /* issue #790 */
 uint8_t u8x8_d_st7565_erc12864_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);  /* issue #790 */
 uint8_t u8x8_d_st7567_pi_132x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_pi_132x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7567_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_enh_dg128064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_enh_dg128064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_enh_dg128064i(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_enh_dg128064i(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_64x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_64x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_hem6432(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_hem6432(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_os12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7567_os12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7567_erc13232(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7567_lw12832(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7571_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7571_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7571_128x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7571_128x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7586s_s028hn118a(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7586s_s028hn118a(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7586s_jlx384160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7586s_erc240160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7586s_erc240160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7586s_ymc240160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7586s_ymc240160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7586s_jlx320160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7588_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7588_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75160_jm16096(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75160_jm16096(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx256128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx256128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -907,26 +928,36 @@ uint8_t u8x8_d_st75256_jlx240160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, voi
 uint8_t u8x8_d_st75256_jlx25664(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx25664(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx172104(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx172104(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx19296(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx19296(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st75256_jlx16080(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75320_jlx320240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);	/* https://github.com/olikraus/u8g2/issues/921 */
 uint8_t u8x8_d_st75320_jlx320240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);	/* https://github.com/olikraus/u8g2/issues/921 */
 uint8_t u8x8_d_nt7534_tg12864r(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* u8x8_d_st7565.c */
 uint8_t u8x8_d_nt7534_tg12864r(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* u8x8_d_st7565.c */
 uint8_t u8x8_d_ld7032_60x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ld7032_60x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ld7032_60x32_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ld7032_60x32_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ld7032_128x36(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_128x64_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_128x64_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_t6963_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_t6963_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1316_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1316_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1316_96x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1317_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 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(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_ssd1318_128x96_xcp(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1320_160x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1320_160x32(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_ssd1320_160x132(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1320_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1322_240x128(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_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_ssd1322_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1362_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1362_206x36(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);
 uint8_t u8x8_d_a2printer_384x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sed1330_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_sed1330_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_sed1330_256x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_sed1330_320x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ra8835_nhd_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ra8835_nhd_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ra8835_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ra8835_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1325_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1325_nhd_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -935,6 +966,7 @@ uint8_t u8x8_d_ssd1327_ws_96x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
 uint8_t u8x8_d_ssd1327_seeed_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_seeed_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_ea_w128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_ea_w128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_midas_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_midas_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1327_zjy_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_ws_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_ws_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_visionox_128x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1327_visionox_128x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1326_er_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1326_er_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -957,6 +989,7 @@ uint8_t u8x8_d_uc1617_jlx128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
 uint8_t u8x8_d_uc1611_ids4073(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* 256x128 */
 uint8_t u8x8_d_uc1611_ids4073(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* 256x128 */
 uint8_t u8x8_d_uc1638_160x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1638_160x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1638_192x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1638_192x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+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_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);
 uint8_t u8x8_d_ks0108_erm19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 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_t7932_150x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* t7932 and hd44102 are compatible */
@@ -977,15 +1010,22 @@ uint8_t u8x8_d_lc7981_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
 uint8_t u8x8_d_lc7981_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_lc7981_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_lc7981_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_lc7981_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_lc7981_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_lc7981_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_lc7981_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ist3020_erc19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ist3020_erc19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ist3088_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ist7920_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ist7920_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_max7219_64x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_max7219_64x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_max7219_32x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_max7219_32x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_max7219_16x16(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_max7219_16x16(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_max7219_8x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_max7219_8x8(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_s1d15e06_160100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_s1d15e06_160100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_s1d15300_lm6023(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_s1d15721_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_s1d15721_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_gu800_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_gu800_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_gu800_160x16(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_gp1287ai_256x50(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_gp1247ai_253x63(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_gp1294ai_256x48(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st7565_jlx12864g109pc(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); // 2023年8月4日 晶联讯12864G-109-PC,12864G-139-P
 uint8_t u8x8_d_st7565_jlx12864g109pc(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); // 2023年8月4日 晶联讯12864G-109-PC,12864G-139-P
 
 
 
 

+ 1 - 0
components/u8g2/u8x8_byte.c

@@ -437,6 +437,7 @@ uint8_t u8x8_byte_sed1520(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_
     case U8X8_MSG_BYTE_START_TRANSFER:
     case U8X8_MSG_BYTE_START_TRANSFER:
       /* cs lines are not supported for the SED1520/SBN1661 */
       /* cs lines are not supported for the SED1520/SBN1661 */
       /* instead, this will select the E1 or E2 line */ 
       /* instead, this will select the E1 or E2 line */ 
+      /* arg_int is set by u8x8_d_sbn1661_122x32() function */
       enable_pin = U8X8_MSG_GPIO_E;
       enable_pin = U8X8_MSG_GPIO_E;
       if ( arg_int != 0 )
       if ( arg_int != 0 )
 	enable_pin = U8X8_MSG_GPIO_CS;
 	enable_pin = U8X8_MSG_GPIO_CS;

+ 2 - 2
components/u8g2/u8x8_d_a2printer.c

@@ -155,7 +155,7 @@ static const u8x8_display_info_t u8x8_a2printer_384x240_display_info =
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
   /* tile_width = */ 48,
   /* tile_width = */ 48,
-  /* tile_hight = */ 30,
+  /* tile_height = */ 30,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 384,
   /* pixel_width = */ 384,
@@ -179,4 +179,4 @@ uint8_t u8x8_d_a2printer_384x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, voi
 
 
   
   
 
 
-  
+  

+ 200 - 0
components/u8g2/u8x8_d_custom.c

@@ -0,0 +1,200 @@
+/*
+
+  u8x8_d_custom.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+  
+*/
+
+
+#include "u8x8.h"
+
+
+
+
+static const uint8_t u8x8_d_custom_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_custom_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_custom_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_custom_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_custom_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_custom_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_custom_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 );	/* custom 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_custom_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_height = */ 4,
+  /* default_x_offset = */ 2,
+  /* flipmode_x_offset = */ 2,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 32
+};
+
+
+static const uint8_t u8x8_d_custom_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),		/* horizontal 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_custom(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    
+  if ( u8x8_d_custom_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_custom_128x32_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_custom_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_custom_128x32_noname_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_custom_128x32_noname_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+

+ 206 - 0
components/u8g2/u8x8_d_gp1247ai.c

@@ -0,0 +1,206 @@
+/*
+
+  u8x8_d_gp1247ai.c
+  
+  252x64
+  
+  https://github.com/olikraus/u8g2/issues/1907
+  https://github.com/olikraus/u8g2/pull/1892  
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2022, 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"
+
+#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))
+
+/* ========== GP1247AI ========== */
+static const u8x8_display_info_t u8x8_gp1247ai_display_info = {
+    /* chip_enable_level = */ 0,
+    /* chip_disable_level = */ 1,
+
+    /* post_chip_enable_wait_ns = */ 240, /* tCS-CLK */
+    /* pre_chip_disable_wait_ns = */ 120, /* tCLK-CS */
+    /* reset_pulse_width_ms = */ 1,       /* Trw     */
+    /* post_reset_wait_ms = */ 1,         /* Trth    */
+    /* sda_setup_time_ns = */ 60,         /* tsu     */
+    /* sck_pulse_width_ns = */ 120,       /* tcyc/2  */
+    /* sck_clock_hz = */ 4000000UL,       /* MAX 4.16 MHz */
+    /* spi_mode = */ 3,                   /* active low, falling edge, MSBFIRST */
+    /* i2c_bus_clock_100kHz = */ 4,       /*         */
+    /* data_setup_time_ns = */ 60,        /* tsu     */
+    /* write_pulse_width_ns = */ 120,     /* tcyc/2  */
+    /* tile_width = */ 32,                /* 32*8=256 memory size */
+    /* tile_height = */ 8,                 /* 8*8=64 memory size */
+    /* default_x_offset = */ 0,           /*         */
+    /* flipmode_x_offset = */ 0,          /*         */
+    /* pixel_width = */ 253,              /* display size */
+    /* pixel_height = */ 63               /* display size */
+};
+static const uint8_t u8x8_d_gp1247ai_init_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x0AA)), /* Software reset */
+    U8X8_END_TRANSFER(),
+    U8X8_DLY(1), /* Wait for reset */
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x078), SWAP8(0x008)), /* Oscillation Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0CC), SWAP8(0x005), SWAP8(0x000)), /* VFD Mode Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAAA(SWAP8(0x0E0), SWAP8(0x0FC), SWAP8(0x03E), SWAP8(0x000)), /* Display Area Setting */
+    U8X8_A4(SWAP8(0x020), SWAP8(0x080), SWAP8(0x080), SWAP8(0x080)),   /* Display Area Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAAAA(SWAP8(0x0B1), SWAP8(0x020), SWAP8(0x03F), SWAP8(0x000), SWAP8(0x001)), /* Internal Speed Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0A0), SWAP8(0x000), SWAP8(0x028)), /* Dimming level Setting (1024 level, 0x3FF max) */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x055)), /* Memory Map Clear */
+    U8X8_END_TRANSFER(),
+    U8X8_DLY(15), /* Wait for memory clear */
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0C0), SWAP8(0x000), SWAP8(0x000)), /* DW1 position setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0D0), SWAP8(0x000), SWAP8(0x040)), /* DW2 position setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x080), SWAP8(0x080)), /* Display Mode Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x061)), /* Standby Mode */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+static const uint8_t u8x8_d_gp1247ai_standby_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x061)), /* Standby */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+static const uint8_t u8x8_d_gp1247ai_wakeup_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x06D)), /* Wake up */
+    U8X8_END_TRANSFER(),
+    U8X8_DLY(1), /* Wait for OSC stabilize */
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x080), SWAP8(0x080)), /* After entering standby mode, the SC bit will be automatically cleared */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+uint8_t u8x8_d_gp1247ai_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    uint8_t *ptr;
+    uint8_t x, y;
+    uint16_t tx_cnt;
+    uint8_t swapped_byte;
+    switch (msg)
+    {
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+        if (arg_int == 0)
+            u8x8_cad_SendSequence(u8x8, u8x8_d_gp1247ai_wakeup_seq);
+        else
+            u8x8_cad_SendSequence(u8x8, u8x8_d_gp1247ai_standby_seq);
+        break;
+#ifdef U8X8_WITH_SET_CONTRAST
+    case U8X8_MSG_DISPLAY_SET_CONTRAST:
+        u8x8_cad_StartTransfer(u8x8);
+        u8x8_cad_SendCmd(u8x8, SWAP8(0x0A0));
+        u8x8_cad_SendArg(u8x8, SWAP8((arg_int * 4) >> 8));   /* Dimming level */
+        u8x8_cad_SendArg(u8x8, SWAP8((arg_int * 4) & 0xFF)); /* Dimming level */
+        u8x8_cad_EndTransfer(u8x8);
+        break;
+#endif
+    case U8X8_MSG_DISPLAY_DRAW_TILE:
+        x = ((u8x8_tile_t *)arg_ptr)->x_pos * 8;
+        y = ((u8x8_tile_t *)arg_ptr)->y_pos * 8;
+
+        u8x8_cad_StartTransfer(u8x8);
+
+        u8x8_cad_SendCmd(u8x8, SWAP8(0x0F0));
+        u8x8_cad_SendArg(u8x8, SWAP8(x));
+        u8x8_cad_SendArg(u8x8, SWAP8(y));
+        u8x8_cad_SendArg(u8x8, SWAP8(0x007)); /* return every 8 pixels */
+        do
+        {
+            ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+            tx_cnt = ((u8x8_tile_t *)arg_ptr)->cnt * 8;
+            while (tx_cnt > 0)
+            {
+                swapped_byte = SWAP8(*ptr);
+                u8x8_cad_SendData(u8x8, 1, &swapped_byte);
+                ptr += 1;
+                tx_cnt -= 1;
+            }
+            arg_int--;
+        } while (arg_int > 0);
+
+        u8x8_cad_EndTransfer(u8x8);
+        break;
+    default:
+        return 0;
+    }
+    return 1;
+}
+uint8_t u8x8_d_gp1247ai_253x63(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_gp1247ai_display_info);
+        break;
+    case U8X8_MSG_DISPLAY_INIT:
+        u8x8_d_helper_display_init(u8x8);
+        u8x8_cad_SendSequence(u8x8, u8x8_d_gp1247ai_init_seq);
+        break;
+    default:
+        return u8x8_d_gp1247ai_common(u8x8, msg, arg_int, arg_ptr);
+    }
+    return 1;
+}

+ 212 - 0
components/u8g2/u8x8_d_gp1287ai.c

@@ -0,0 +1,212 @@
+/*
+
+  u8x8_d_gp1287ai.c
+  
+  https://github.com/olikraus/u8g2/issues/1907
+  https://github.com/olikraus/u8g2/pull/1892  
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2022, 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"
+
+#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))
+
+/* ========== GP1287AI ========== */
+static const u8x8_display_info_t u8x8_gp1287ai_display_info = {
+    /* chip_enable_level = */ 0,
+    /* chip_disable_level = */ 1,
+
+    /* post_chip_enable_wait_ns = */ 240, /* tCS-CLK */
+    /* pre_chip_disable_wait_ns = */ 120, /* tCLK-CS */
+    /* reset_pulse_width_ms = */ 1,       /* Trw     */
+    /* post_reset_wait_ms = */ 1,         /* Trth    */
+    /* sda_setup_time_ns = */ 60,         /* tsu     */
+    /* sck_pulse_width_ns = */ 120,       /* tcyc/2  */
+    /* sck_clock_hz = */ 4000000UL,       /* MAX 4.16 MHz */
+    /* spi_mode = */ 3,                   /* active low, falling edge, MSBFIRST */
+    /* i2c_bus_clock_100kHz = */ 4,       /*         */
+    /* data_setup_time_ns = */ 60,        /* tsu     */
+    /* write_pulse_width_ns = */ 120,     /* tcyc/2  */
+    /* tile_width = */ 32,                /* 32*8=256 memory size */
+    /* tile_height = */ 7,                 /* 7*8=56 memory size */
+    /* default_x_offset = */ 0,           /*         */
+    /* flipmode_x_offset = */ 0,          /*         */
+    /* pixel_width = */ 256,              /* display size */
+    /* pixel_height = */ 50               /* display size */
+};
+static const uint8_t u8x8_d_gp1287ai_init_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x0AA)), /* Software reset */
+    U8X8_END_TRANSFER(),
+    U8X8_DLY(1), /* Wait for reset */
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x078), SWAP8(0x008)), /* Oscillation Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0CC), SWAP8(0x002), SWAP8(0x000)), /* VFD Mode Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAAA(SWAP8(0x0E0), SWAP8(0x0FF), SWAP8(0x031), SWAP8(0x000)), /* Display Area Setting */
+    U8X8_A4(SWAP8(0x020), SWAP8(0x000), SWAP8(0x000), SWAP8(0x080)),   /* Display Area Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAAAA(SWAP8(0x0B1), SWAP8(0x020), SWAP8(0x03F), SWAP8(0x000), SWAP8(0x001)), /* Internal Speed Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0A0), SWAP8(0x000), SWAP8(0x028)), /* Dimming level Setting (1024 level, 0x3FF max) */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x055)), /* Memory Map Clear */
+    U8X8_END_TRANSFER(),
+    U8X8_DLY(15), /* Waiting for memory clear */
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0C0), SWAP8(0x000), SWAP8(0x004)), /* DW1 position setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0D0), SWAP8(0x000), SWAP8(0x03C)), /* DW2 position setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x090), SWAP8(0x000)), /* Internal Command */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x008), SWAP8(0x000)), /* T1 INT Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x080), SWAP8(0x000)), /* Display Mode Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x061)), /* Standby Mode */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+static const uint8_t u8x8_d_gp1287ai_standby_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x061)), /* Standby */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+static const uint8_t u8x8_d_gp1287ai_wakeup_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x06D)), /* Wake up */
+    U8X8_END_TRANSFER(),
+    U8X8_DLY(1), /* Wait for OSC stabilize */
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x080), SWAP8(0x000)), /* After entering standby mode, the SC bit will be automatically cleared */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+uint8_t u8x8_d_gp1287ai_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    uint8_t *ptr;
+    uint8_t x, y;
+    uint16_t tx_cnt;
+    uint8_t swapped_byte;
+    switch (msg)
+    {
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+        if (arg_int == 0)
+            u8x8_cad_SendSequence(u8x8, u8x8_d_gp1287ai_wakeup_seq);
+        else
+            u8x8_cad_SendSequence(u8x8, u8x8_d_gp1287ai_standby_seq);
+        break;
+#ifdef U8X8_WITH_SET_CONTRAST
+    case U8X8_MSG_DISPLAY_SET_CONTRAST:
+        u8x8_cad_StartTransfer(u8x8);
+        u8x8_cad_SendCmd(u8x8, SWAP8(0x0A0));
+        u8x8_cad_SendArg(u8x8, SWAP8((arg_int * 4) >> 8));   /* Dimming level */
+        u8x8_cad_SendArg(u8x8, SWAP8((arg_int * 4) & 0xFF)); /* Dimming level */
+        u8x8_cad_EndTransfer(u8x8);
+        break;
+#endif
+    case U8X8_MSG_DISPLAY_DRAW_TILE:
+        x = ((u8x8_tile_t *)arg_ptr)->x_pos * 8;
+        y = ((u8x8_tile_t *)arg_ptr)->y_pos * 8 + 4;
+
+        u8x8_cad_StartTransfer(u8x8);
+
+        u8x8_cad_SendCmd(u8x8, SWAP8(0x0F0));
+        u8x8_cad_SendArg(u8x8, SWAP8(x));
+        u8x8_cad_SendArg(u8x8, SWAP8(y));
+        u8x8_cad_SendArg(u8x8, SWAP8(0x007)); /* return every 8 pixels */
+        do
+        {
+            ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+            tx_cnt = ((u8x8_tile_t *)arg_ptr)->cnt * 8;
+            while (tx_cnt > 0)
+            {
+                swapped_byte = SWAP8(*ptr);
+                u8x8_cad_SendData(u8x8, 1, &swapped_byte);
+                ptr += 1;
+                tx_cnt -= 1;
+            }
+            arg_int--;
+        } while (arg_int > 0);
+
+        u8x8_cad_EndTransfer(u8x8);
+        break;
+    default:
+        return 0;
+    }
+    return 1;
+}
+uint8_t u8x8_d_gp1287ai_256x50(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_gp1287ai_display_info);
+        break;
+    case U8X8_MSG_DISPLAY_INIT:
+        u8x8_d_helper_display_init(u8x8);
+        u8x8_cad_SendSequence(u8x8, u8x8_d_gp1287ai_init_seq);
+        break;
+    default:
+        return u8x8_d_gp1287ai_common(u8x8, msg, arg_int, arg_ptr);
+    }
+    return 1;
+}

+ 182 - 0
components/u8g2/u8x8_d_gp1294ai.c

@@ -0,0 +1,182 @@
+/*
+
+  u8x8_d_gp1294ai.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2023, 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"
+
+#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))
+
+/* ========== GP1294AI ========== */
+static const u8x8_display_info_t u8x8_gp1294ai_display_info = {
+    /* chip_enable_level = */ 0,
+    /* chip_disable_level = */ 1,
+
+    /* post_chip_enable_wait_ns = */ 240, /* tCS-CLK */
+    /* pre_chip_disable_wait_ns = */ 120, /* tCLK-CS */
+    /* reset_pulse_width_ms = */ 1,       /* Trw     */
+    /* post_reset_wait_ms = */ 1,         /* Trth    */
+    /* sda_setup_time_ns = */ 60,         /* tsu     */
+    /* sck_pulse_width_ns = */ 120,       /* tcyc/2  */
+    /* sck_clock_hz = */ 4000000UL,       /* MAX 4.16 MHz */
+    /* spi_mode = */ 3,                   /* active low, falling edge, MSBFIRST */
+    /* i2c_bus_clock_100kHz = */ 4,       /*         */
+    /* data_setup_time_ns = */ 60,        /* tsu     */
+    /* write_pulse_width_ns = */ 120,     /* tcyc/2  */
+    /* tile_width = */ 32,                /* 32*8=256 memory size */
+    /* tile_height = */ 6,                /* 6*8=48 memory size */
+    /* default_x_offset = */ 0,           /*         */
+    /* flipmode_x_offset = */ 0,          /*         */
+    /* pixel_width = */ 256,              /* display size */
+    /* pixel_height = */ 48               /* display size */
+};
+static const uint8_t u8x8_d_gp1294ai_init_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x0AA)), /* Software reset */
+    U8X8_END_TRANSFER(),
+    U8X8_DLY(1), /* Wait for reset */
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAAA(SWAP8(0x0CC), SWAP8(0x001), SWAP8(0x01F), SWAP8(0x000)), /* VFD Mode Setting */
+    U8X8_A4(SWAP8(0x0FF), SWAP8(0x02F), SWAP8(0x000), SWAP8(0x020)),
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0A0), SWAP8(0x028), SWAP8(0x000)), /* Dimming level Setting (1024 level, 0x3FF max) */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CAA(SWAP8(0x0C0), SWAP8(0x000), SWAP8(0x000)), /* DW1 position setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x080), SWAP8(0x010)), /* Display Mode Setting (Scan STOP) */
+    U8X8_END_TRANSFER(),
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x008), SWAP8(0x000)), /* T1 INT Setting */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+static const uint8_t u8x8_d_gp1294ai_standby_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x061)), /* Standby */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+static const uint8_t u8x8_d_gp1294ai_wakeup_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_C(SWAP8(0x06D)), /* Wake up */
+    U8X8_END_TRANSFER(),
+    U8X8_DLY(1), /* Wait for OSC stabilize */
+
+    U8X8_START_TRANSFER(),
+    U8X8_CA(SWAP8(0x080), SWAP8(0x000)), /* After entering standby mode, the SC bit will be automatically cleared */
+    U8X8_END_TRANSFER(),
+
+    U8X8_END() /* end of sequence */
+};
+uint8_t u8x8_d_gp1294ai_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    uint8_t *ptr;
+    uint8_t x, y;
+    uint16_t tx_cnt;
+    uint8_t swapped_byte;
+    switch (msg)
+    {
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+        if (arg_int == 0)
+            u8x8_cad_SendSequence(u8x8, u8x8_d_gp1294ai_wakeup_seq);
+        else
+            u8x8_cad_SendSequence(u8x8, u8x8_d_gp1294ai_standby_seq);
+        break;
+#ifdef U8X8_WITH_SET_CONTRAST
+    case U8X8_MSG_DISPLAY_SET_CONTRAST:
+        u8x8_cad_StartTransfer(u8x8);
+        u8x8_cad_SendCmd(u8x8, SWAP8(0x0A0));
+        u8x8_cad_SendArg(u8x8, SWAP8((arg_int * 4) & 0xFF)); /* Dimming level */
+        u8x8_cad_SendArg(u8x8, SWAP8((arg_int * 4) >> 8));   /* Dimming level */
+        u8x8_cad_EndTransfer(u8x8);
+        break;
+#endif
+    case U8X8_MSG_DISPLAY_DRAW_TILE:
+        x = ((u8x8_tile_t *)arg_ptr)->x_pos * 8;
+        y = ((u8x8_tile_t *)arg_ptr)->y_pos * 8 + 4;
+
+        u8x8_cad_StartTransfer(u8x8);
+
+        u8x8_cad_SendCmd(u8x8, SWAP8(0x0F0));
+        u8x8_cad_SendArg(u8x8, SWAP8(x));
+        u8x8_cad_SendArg(u8x8, SWAP8(y));
+        u8x8_cad_SendArg(u8x8, SWAP8(0x007)); /* return every 8 pixels */
+        do
+        {
+            ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+            tx_cnt = ((u8x8_tile_t *)arg_ptr)->cnt * 8;
+            while (tx_cnt > 0)
+            {
+                swapped_byte = SWAP8(*ptr);
+                u8x8_cad_SendData(u8x8, 1, &swapped_byte);
+                ptr += 1;
+                tx_cnt -= 1;
+            }
+            arg_int--;
+        } while (arg_int > 0);
+
+        u8x8_cad_EndTransfer(u8x8);
+        break;
+    default:
+        return 0;
+    }
+    return 1;
+}
+uint8_t u8x8_d_gp1294ai_256x48(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_gp1294ai_display_info);
+        break;
+    case U8X8_MSG_DISPLAY_INIT:
+        u8x8_d_helper_display_init(u8x8);
+        u8x8_cad_SendSequence(u8x8, u8x8_d_gp1294ai_init_seq);
+        u8x8_ClearDisplay(u8x8); /* GP1294AI does not have the command to clear the memory and needs to be cleared manually  */
+        u8x8_cad_SendSequence(u8x8, u8x8_d_gp1294ai_standby_seq);
+        break;
+    default:
+        return u8x8_d_gp1294ai_common(u8x8, msg, arg_int, arg_ptr);
+    }
+    return 1;
+}

+ 86 - 3
components/u8g2/u8x8_d_gu800.c

@@ -103,7 +103,7 @@ uint8_t u8x8_d_gu800_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
 #endif
 #endif
 #ifdef U8X8_WITH_SET_CONTRAST
 #ifdef U8X8_WITH_SET_CONTRAST
     case U8X8_MSG_DISPLAY_SET_CONTRAST:
     case U8X8_MSG_DISPLAY_SET_CONTRAST:
-      u8x8_cad_SendCmd(u8x8, 0x40 | (arg_int >> 4) );	/* GU800 has range from 0..15 */
+      u8x8_cad_SendCmd(u8x8, 0x4f - ((arg_int >> 4)&0x0f) );	/* GU800 has range from 0..15, max brightness is 0x040  */
       break;
       break;
 #endif
 #endif
     case U8X8_MSG_DISPLAY_DRAW_TILE:
     case U8X8_MSG_DISPLAY_DRAW_TILE:
@@ -137,6 +137,8 @@ uint8_t u8x8_d_gu800_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
   return 1;
   return 1;
 }
 }
 
 
+/*=================================================*/
+
 static const uint8_t u8x8_d_gu800_128x64_init_seq[] = {
 static const uint8_t u8x8_d_gu800_128x64_init_seq[] = {
     
     
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
@@ -156,7 +158,7 @@ static const uint8_t u8x8_d_gu800_128x64_init_seq[] = {
   
   
   U8X8_CA(0x70, 0),                             /* horizontal shift */
   U8X8_CA(0x70, 0),                             /* horizontal shift */
   U8X8_C(0xb0),                                 /* vertical shift */  
   U8X8_C(0xb0),                                 /* vertical shift */  
-  U8X8_C(0x4f),                                 /* max brightness */
+  U8X8_C(0x40),                                 /* min (0x04f) / max (0x040) brightness */
   U8X8_C(0x84),                                 /* x increment */
   U8X8_C(0x84),                                 /* x increment */
   
   
   // U8X8_CA(0x024, 0x040)              /* display on */
   // U8X8_CA(0x024, 0x040)              /* display on */
@@ -183,7 +185,7 @@ static const u8x8_display_info_t u8x8_d_gu800_128x64_display_info =
   /* data_setup_time_ns = */ 40,    /* GU800: Min 40ns per datasheet */
   /* data_setup_time_ns = */ 40,    /* GU800: Min 40ns per datasheet */
   /* write_pulse_width_ns = */ 150, /* GU800: Min 150ns per datasheet */
   /* write_pulse_width_ns = */ 150, /* GU800: Min 150ns per datasheet */
   /* tile_width = */ 16,            /* width of 16*8=128 pixel */
   /* tile_width = */ 16,            /* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -211,3 +213,84 @@ uint8_t u8x8_d_gu800_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
   }
   }
   return 1;
   return 1;
 }
 }
+
+/*=================================================*/
+/* https://github.com/olikraus/u8g2/issues/1970 */
+
+static const uint8_t u8x8_d_gu800_160x16_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_C(0x05f),                                /* clear all RAM, clear address counters */
+  U8X8_DLY(1),                                  /* delay for 1 ms (see datasheet) */
+  
+  /* configure all area as graphics RAM */
+  U8X8_CA(0x62,0), U8X8_D1(0xff),
+  U8X8_CA(0x62,1), U8X8_D1(0xff),
+  U8X8_CA(0x62,2), U8X8_D1(0xff),
+  U8X8_CA(0x62,3), U8X8_D1(0xff),
+  U8X8_CA(0x62,4), U8X8_D1(0xff),
+  U8X8_CA(0x62,5), U8X8_D1(0xff),
+  U8X8_CA(0x62,6), U8X8_D1(0xff),
+  U8X8_CA(0x62,7), U8X8_D1(0xff),
+  
+  U8X8_CA(0x70, 0),                             /* horizontal shift */
+  U8X8_C(0xb0),                                 /* vertical shift */  
+  U8X8_C(0x40),                                 /* min (0x04f) / max (0x040) brightness */
+  U8X8_C(0x84),                                 /* x increment */
+  
+  // U8X8_CA(0x024, 0x040)              /* display on */
+  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+static const u8x8_display_info_t u8x8_d_gu800_160x16_display_info =
+{
+  /* chip_enable_level = */ 0,      /* GU800: CSS signal */
+  /* chip_disable_level = */ 1,     /* GU800: CSS signal */
+  
+  /* post_chip_enable_wait_ns = */ 40,
+  /* pre_chip_disable_wait_ns = */ 150,
+  /* reset_pulse_width_ms = */ 2,   /* GU800: Unspecified in datasheet */
+  /* post_reset_wait_ms = */ 2,     /* GU800: Min 1.5ms per datasheet */
+  /* sda_setup_time_ns = */ 40,     /* GU800: 40ns according to the timing diagram */
+  /* sck_pulse_width_ns = */ 80,    /* GU800: Min 80ns per datasheet */
+  /* sck_clock_hz = */ 4000000UL,
+  /* spi_mode = */ 3,               /* active high, rising edge, ISSUE 1970 */
+  /* i2c_bus_clock_100kHz = */ 4,   /* GU800: Not used */
+  /* data_setup_time_ns = */ 40,    /* GU800: Min 40ns per datasheet */
+  /* write_pulse_width_ns = */ 150, /* GU800: Min 150ns per datasheet */
+  /* tile_width = */ 20,            /* width of 8*20=160 pixel */
+  /* tile_height = */ 2,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 160,
+  /* pixel_height = */ 16
+};
+
+
+uint8_t u8x8_d_gu800_160x16(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  
+  if ( u8x8_d_gu800_common(u8x8, msg, arg_int, arg_ptr) )
+    return 1;
+  
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_d_gu800_160x16_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_gu800_160x16_init_seq);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+/*=================================================*/
+

+ 2 - 2
components/u8g2/u8x8_d_hd44102.c

@@ -165,7 +165,7 @@ static const u8x8_display_info_t u8x8_hd44102_150x32_display_info =
   /* data_setup_time_ns = */ 200,
   /* data_setup_time_ns = */ 200,
   /* write_pulse_width_ns = */ 250,	/* KS0108/HD44102: actially 450 ns, but additional 200 ns are added by the byte transfer function */
   /* write_pulse_width_ns = */ 250,	/* KS0108/HD44102: actially 450 ns, but additional 200 ns are added by the byte transfer function */
   /* tile_width = */ 19,		/* width of 19*8=152 pixel */
   /* tile_width = */ 19,		/* width of 19*8=152 pixel */
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 150,
   /* pixel_width = */ 150,
@@ -260,7 +260,7 @@ static const u8x8_display_info_t u8x8_hd44102_100x64_display_info =
   /* data_setup_time_ns = */ 200,
   /* data_setup_time_ns = */ 200,
   /* write_pulse_width_ns = */ 250,	/* KS0108/HD44102: actially 450 ns, but additional 200 ns are added by the byte transfer function */
   /* write_pulse_width_ns = */ 250,	/* KS0108/HD44102: actially 450 ns, but additional 200 ns are added by the byte transfer function */
   /* tile_width = */ 13,		/* width of 13*8=104 pixel */
   /* tile_width = */ 13,		/* width of 13*8=104 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 100,
   /* pixel_width = */ 100,

+ 1 - 1
components/u8g2/u8x8_d_il3820_296x128.c

@@ -156,7 +156,7 @@ static const u8x8_display_info_t u8x8_il3820_296x128_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 37,		/* 37*8 = 296 */
   /* tile_width = */ 37,		/* 37*8 = 296 */
-  /* tile_hight = */ 16,		/* 16*8 = 128 */	
+  /* tile_height = */ 16,		/* 16*8 = 128 */	
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 296,
   /* pixel_width = */ 296,

+ 1 - 1
components/u8g2/u8x8_d_ist3020.c

@@ -88,7 +88,7 @@ static const u8x8_display_info_t u8x8_ist3020_erc19264_display_info =
   /* data_setup_time_ns = */ 40,	/* IST3020 datasheet, page 54 */
   /* data_setup_time_ns = */ 40,	/* IST3020 datasheet, page 54 */
   /* write_pulse_width_ns = */ 60,	/* IST3020 datasheet, page 54 */
   /* write_pulse_width_ns = */ 60,	/* IST3020 datasheet, page 54 */
   /* tile_width = */ 24,		/* width of 24*8=192 pixel */
   /* tile_width = */ 24,		/* width of 24*8=192 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 64,
   /* flipmode_x_offset = */ 64,
   /* pixel_width = */ 192,
   /* pixel_width = */ 192,

+ 280 - 0
components/u8g2/u8x8_d_ist3088.c

@@ -0,0 +1,280 @@
+/*
+
+  u8x8_d_ist3088.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2019, 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.  
+
+
+  IST3088: 320x240 monochrome LCD, 16 gray levels with B/W mode
+  
+  https://github.com/olikraus/u8g2/issues/1887
+  
+  CAD: 011
+  commands and arg/data are always 16 bit, MSB first
+  
+*/
+
+
+#include "u8x8.h"
+
+/* powersave: maybe we could go to sleep mode, see register 3 */
+static const uint8_t u8x8_d_ist3088_320x240_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CCAA(0x0, 0x07, 0x00, 0x01), 			// Display Control Bit 2: BW, 1: Invert, 0: Display enable
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ist3088_320x240_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CCAA(0x0, 0x07, 0x00, 0x00), 			// Display Control Bit 2: BW, 1: Invert, 0: Display enable
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ist3088_320x240_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CCAA(0x0, 0x01, 0x00, 0x00), 			// Driver Control, 1/240 Duty
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ist3088_320x240_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CCAA(0x0, 0x01, 0x00, 0x00), 			// Driver Control, 1/240 Duty
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+
+
+/*===================================================*/
+
+static uint8_t u8x8_d_ist3088_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  //uint16_t x;
+  int i;
+  uint8_t y;
+  uint8_t 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_ist3088_320x240_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_ist3088_320x240_init_seq);    
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ist3088_320x240_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ist3088_320x240_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ist3088_320x240_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ist3088_320x240_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, 0x00 );
+      u8x8_cad_SendCmd(u8x8, 0x05 );
+      u8x8_cad_SendArg(u8x8, 0 );	
+      u8x8_cad_SendArg(u8x8, arg_int );	
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+#endif
+    case U8X8_MSG_DISPLAY_DRAW_TILE:
+      /*
+      x = ((u8x8_tile_t *)arg_ptr)->x_pos;    
+      x *= 8;
+      x += u8x8->x_offset;
+    */
+
+      y = (((u8x8_tile_t *)arg_ptr)->y_pos);
+      y*=8;
+
+      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, 0x0);
+          u8x8_cad_SendCmd(u8x8, 0x8);
+          u8x8_cad_SendArg(u8x8, y); 
+          u8x8_cad_SendArg(u8x8, 0 );
+
+
+          u8x8_cad_SendCmd(u8x8, 0x0);		// write data 
+          u8x8_cad_SendCmd(u8x8, 0x9);		// write data 
+          
+          
+          //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 */
+          
+          ptr += u8x8->display_info->tile_width;
+          y ++;
+        }
+
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+/*===================================================*/
+
+/*
+    SdCmd(0x01);                // driver control
+	SdData(0x00); SdData(0x00); // c1-->c240 s1-->s240 duty=1/240
+    SdCmd(0x02);                // driver control
+	SdData(0x01); SdData(0x4c);	//0x15
+    SdCmd(0x03);                // power control
+	SdData(0x00); SdData(0x70); // VC VR Vf=1
+    SdCmd(0x04);                // power control
+	SdData(0x04); SdData(0x61); //0x61  //1/14b
+    SdCmd(0x05);                // CT control
+	SdData(0x00); SdData(0x6a); // 0X76 
+    SdCmd(0x06);                // CT control
+	SdData(0x00); SdData(0x03); 
+    SdCmd(0x23);                // B/W MODE,16G NEED REMOVE
+	SdData(0x00); SdData(0x04); //04:mono
+    SdCmd(0x28);                // OSC
+	SdData(0x00); SdData(0x0c);
+    SdCmd(0x37);                
+        SdData(0x00); SdData(0x12);
+    SdCmd(0x07);                
+        SdData(0x00); SdData(0x01);
+*/
+
+/* https://github.com/olikraus/u8g2/issues/1887 */
+static const uint8_t u8x8_d_ist3088_320x240_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+
+  /* disableLCD */
+  U8X8_CCAA(0x0, 0x07, 0x00, 0x00), 			// Display Control Bit 2: BW, 1: Invert, 0: Display enable
+
+  U8X8_CCAA(0x0, 0x01, 0x00, 0x00), 			// Driver Control, 1/240 Duty
+  U8X8_CCAA(0x0, 0x02, 0x01, 0x4c), 			// Polarity Control
+
+  U8X8_CCAA(0x0, 0x06, 0x00, 0x03), 			// Entry mode: h/v increment  
+  //U8X8_CCAA(0x0, 0x04, 0x07, 0x61), 			// Power Control 2: 0x07: 1/16 Bias, Vout1 x 4
+  U8X8_CCAA(0x0, 0x04, 0x04, 0x61), 			// Power Control 2: 0x07: 1/16 Bias, Vout1 x 4
+  U8X8_CCAA(0x0, 0x05, 0x00, 0x6a), 			// Contrast, 0..255, 
+
+  U8X8_CCAA(0x0, 0x03, 0x00, 0x40), 			// Enable voltage converter 
+  U8X8_DLY(10),
+  U8X8_CCAA(0x0, 0x03, 0x00, 0x60), 			// Enable voltage regulator 
+  U8X8_DLY(10),
+  U8X8_CCAA(0x0, 0x03, 0x00, 0x70), 			// Enable voltage follower 
+  U8X8_DLY(10),
+
+  U8X8_CCAA(0x0, 0x23, 0x00, 0x04), 			// Monochrome mode
+  U8X8_CCAA(0x0, 0x28, 0x00, 0x0c), 			// Frame Rate Control
+  U8X8_CCAA(0x0, 0x37, 0x00, 0x01), 			// Frame Rate Control
+  U8X8_CCAA(0x0, 0x0d, 39, 0x00), 			// X End and X Start
+  
+  U8X8_CCAA(0x0, 0x0e, 239, 0x00), 			// Y End and Y Start
+
+  /* enable LCD (will be done by powersave0) */
+  //U8X8_CCAA(0x0, 0x07, 0x00, 0x01), 			// Display Control Bit 2: BW, 1: Invert, 0: Display enable
+    
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()           			/* end of sequence */
+};
+
+
+
+
+static const u8x8_display_info_t u8x8_ist3088_320x240_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 110,
+  /* pre_chip_disable_wait_ns = */ 110,
+  /* reset_pulse_width_ms = */ 10, 	
+  /* post_reset_wait_ms = */ 10, 		/**/
+  /* sda_setup_time_ns = */ 110,		/* */
+  /* sck_pulse_width_ns = */ 125,	/*  */
+  /* sck_clock_hz = */ 4000000UL,	/* 250ns cycle, see page 49 of the IST3088 datasheet*/
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,	/* 400KHz, IST8033 das not include a I2C interface */
+  /* data_setup_time_ns = */ 70,
+  /* write_pulse_width_ns = */ 60,	
+  /* tile_width = */ 40,
+  /* tile_height = */ 30,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 320,
+  /* pixel_height = */ 240
+};
+
+uint8_t u8x8_d_ist3088_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    
+  if ( u8x8_d_ist3088_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_ist3088_320x240_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ist3088_320x240_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}

+ 1 - 1
components/u8g2/u8x8_d_ist7920.c

@@ -86,7 +86,7 @@ static const u8x8_display_info_t u8x8_ist7920_128x128_display_info =
   /* data_setup_time_ns = */ 60,	/* IST7920 datasheet, page 47 */
   /* data_setup_time_ns = */ 60,	/* IST7920 datasheet, page 47 */
   /* write_pulse_width_ns = */ 150,	/* IST7920 datasheet, page 47 */
   /* write_pulse_width_ns = */ 150,	/* IST7920 datasheet, page 47 */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 2 - 2
components/u8g2/u8x8_d_ks0108.c

@@ -120,7 +120,7 @@ static const u8x8_display_info_t u8x8_ks0108_128x64_display_info =
   /* data_setup_time_ns = */ 200,
   /* 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 */
   /* 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_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -227,7 +227,7 @@ static const u8x8_display_info_t u8x8_ks0108_192x64_display_info =
   /* data_setup_time_ns = */ 200,
   /* 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 */
   /* 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_width = */ 24,		/* width of 24*8=192 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 192,
   /* pixel_width = */ 192,

+ 76 - 4
components/u8g2/u8x8_d_lc7981.c

@@ -203,7 +203,7 @@ static const u8x8_display_info_t u8x8_lc7981_160x80_display_info =
   /* data_setup_time_ns = */ 220,	
   /* data_setup_time_ns = */ 220,	
   /* write_pulse_width_ns = */ 20,	
   /* write_pulse_width_ns = */ 20,	
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
-  /* tile_hight = */ 10,
+  /* tile_height = */ 10,
   /* default_x_offset = */ 0,	
   /* default_x_offset = */ 0,	
   /* flipmode_x_offset = */ 0,	
   /* flipmode_x_offset = */ 0,	
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,
@@ -275,7 +275,7 @@ static const u8x8_display_info_t u8x8_lc7981_160x160_display_info =
   /* data_setup_time_ns = */ 220,	
   /* data_setup_time_ns = */ 220,	
   /* write_pulse_width_ns = */ 20,	
   /* write_pulse_width_ns = */ 20,	
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
-  /* tile_hight = */ 20,
+  /* tile_height = */ 20,
   /* default_x_offset = */ 0,	
   /* default_x_offset = */ 0,	
   /* flipmode_x_offset = */ 0,	
   /* flipmode_x_offset = */ 0,	
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,
@@ -347,7 +347,7 @@ static const u8x8_display_info_t u8x8_lc7981_240x128_display_info =
   /* data_setup_time_ns = */ 220,	
   /* data_setup_time_ns = */ 220,	
   /* write_pulse_width_ns = */ 20,	
   /* write_pulse_width_ns = */ 20,	
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,	
   /* default_x_offset = */ 0,	
   /* flipmode_x_offset = */ 0,	
   /* flipmode_x_offset = */ 0,	
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -420,7 +420,7 @@ static const u8x8_display_info_t u8x8_lc7981_240x64_display_info =
   /* data_setup_time_ns = */ 220,	
   /* data_setup_time_ns = */ 220,	
   /* write_pulse_width_ns = */ 20,	
   /* write_pulse_width_ns = */ 20,	
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,	
   /* default_x_offset = */ 0,	
   /* flipmode_x_offset = */ 0,	
   /* flipmode_x_offset = */ 0,	
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -468,3 +468,75 @@ uint8_t u8x8_d_lc7981_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
   return 1;
   return 1;
 }
 }
 
 
+
+/*================================================*/
+/* LC7981 128x128 LCD, https://github.com/olikraus/u8g2/issues/1913*/
+
+static const u8x8_display_info_t u8x8_lc7981_128x128_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 = */ 16,		/* width of 16*8=128 pixel */
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 0,	
+  /* flipmode_x_offset = */ 0,	
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 128
+};
+
+static const uint8_t u8x8_d_lc7981_128x128_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, 128/8-1),		/* number of chars/byte width of the screen */
+  U8X8_CA(0x03, 128),			/* time division, issue https://github.com/olikraus/u8g2/issues/1581 */
+  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_128x128(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_128x128_display_info);
+	break;
+      case U8X8_MSG_DISPLAY_INIT:
+	u8x8_d_helper_display_init(u8x8);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_lc7981_128x128_init_seq);
+	break;
+      default:
+	return 0;		/* msg unknown */
+    }
+  }
+  return 1;
+}
+

+ 163 - 4
components/u8g2/u8x8_d_ld7032_60x32.c

@@ -2,10 +2,12 @@
 
 
   u8x8_d_ld7032_60x32.c
   u8x8_d_ld7032_60x32.c
   Note: Flip Mode is NOT supported
   Note: Flip Mode is NOT supported
+  
+  Also contains 128x36 OLED variant
 
 
   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
   Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
 
 
-  Copyright (c) 2016, olikraus@gmail.com
+  Copyright (c) 2023, olikraus@gmail.com
   All rights reserved.
   All rights reserved.
 
 
   Redistribution and use in source and binary forms, with or without modification, 
   Redistribution and use in source and binary forms, with or without modification, 
@@ -223,7 +225,7 @@ static const u8x8_display_info_t u8x8_ld7032_60x32_display_info =
   /* data_setup_time_ns = */ 20,
   /* data_setup_time_ns = */ 20,
   /* write_pulse_width_ns = */ 40,	
   /* write_pulse_width_ns = */ 40,	
   /* tile_width = */ 8,
   /* tile_width = */ 8,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 60,
   /* pixel_width = */ 60,
@@ -272,11 +274,13 @@ static const uint8_t u8x8_d_ld7032_60x32_alt_init_seq[] = {
   U8X8_CA(0x48, 0x03),		  	
   U8X8_CA(0x48, 0x03),		  	
   U8X8_CA(0x17, 0x00),         
   U8X8_CA(0x17, 0x00),         
   U8X8_CA(0x13, 0x01),        
   U8X8_CA(0x13, 0x01),        
-  U8X8_CA(0x3F, 0x11),
+  U8X8_CA(0x3F, 0x11),          // internal regulator enabled, vcc_c * 0.7 
   U8X8_CA(0x3D, 0x00),
   U8X8_CA(0x3D, 0x00),
 
 
   U8X8_END_TRANSFER(),             	/* disable chip */
   U8X8_END_TRANSFER(),             	/* disable chip */
-  U8X8_END()             			/* end of sequence */};
+  U8X8_END()             			/* end of sequence */
+  
+  };
 
 
 uint8_t u8x8_d_ld7032_60x32_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 uint8_t u8x8_d_ld7032_60x32_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
 {
@@ -296,3 +300,158 @@ uint8_t u8x8_d_ld7032_60x32_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
     return u8x8_d_ld7032_generic(u8x8, msg, arg_int, arg_ptr);
     return u8x8_d_ld7032_generic(u8x8, msg, arg_int, arg_ptr);
 }
 }
 
 
+/*==========================================*/
+/*
+  128x36 Flip Mode is NOT supported
+  see https://github.com/olikraus/u8g2/issues/2135
+*/
+
+static uint8_t u8x8_d_ld7032_128_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, 0x00f );
+      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, 0x027 );
+      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_128x36_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 = */ 16,
+  /* tile_height = */ 5,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 36
+};
+
+static const uint8_t u8x8_d_ld7032_128x36_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+
+  U8X8_CA(0x14, 0x00),		  		// standby mode
+  U8X8_CA(0x02, 0x00),		  		// display off
+  U8X8_CA(0x1A, 0x05),		  		// frame frequency
+  U8X8_CA(0x1D, 0x00),		  	        // data write direction (datasheet: 1d 0b
+  U8X8_CA(0x09, 0x00),	      		        // scan direction
+  U8X8_CAA(0x30, 0x00, 0x7F),             // column driver active range 
+  U8X8_CAA(0x32, 0x04, 0x27),           // row driver active range
+  U8X8_CA(0x34, 0x00),				// start line
+  U8X8_CA(0x35, 0x0f),		                // end line
+  U8X8_CA(0x36, 0x04),	                        // row start line
+  U8X8_CA(0x37, 0x27),			        // row end line
+  U8X8_CA(0x38, 0x00),                          // x disp start, default 0        
+  U8X8_CA(0x39, 0x00),                          // y disp start, default 0
+  U8X8_CA(0x10, 0x1f),		  	        // peak pulse width
+  U8X8_CA(0x16, 0x05),		                // pulse delay width  	
+  U8X8_CA(0x18, 0x1f),		  		// pre charge width
+  U8X8_CA(0x12, 0x3F),		  	        // contrast control
+  U8X8_CA(0x44, 0x02),		  		// PreC select, default: 2
+  //U8X8_CA(0x48, 0x00),		  	        // row overlap, default: 0 (was 3)
+  U8X8_CA(0x17, 0x00),                          // row scan, default: 0
+  U8X8_CA(0x13, 0x01),                          // scan mode sequence
+  //U8X8_CA(0x3F, 0x11),                         // VCC R Selection, default: 0 (int. reg. disabled, vcc_c*0.8)
+  U8X8_CA(0x3D, 0x01),                          // vdd selection 0: 2.8V-3.5, 1: 1.8V (1.65-2.5V)
+
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+  
+  };
+
+uint8_t u8x8_d_ld7032_128x36(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_128x36_display_info);
+      return 1;
+    }
+
+    if ( msg ==U8X8_MSG_DISPLAY_INIT )
+    {
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ld7032_128x36_init_seq);    
+      return 1;
+    }
+    
+    return u8x8_d_ld7032_128_generic(u8x8, msg, arg_int, arg_ptr);
+}

+ 7 - 7
components/u8g2/u8x8_d_ls013b7dh03.c

@@ -55,12 +55,12 @@ static const u8x8_display_info_t u8x8_ls013b7dh03_128x128_display_info =
   /* sda_setup_time_ns = */ 227,	/* 227 nsec according to the datasheet */		
   /* sda_setup_time_ns = */ 227,	/* 227 nsec according to the datasheet */		
   /* sck_pulse_width_ns = */  255,	/* 450 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 */
   /* 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 */
+  /* spi_mode = */ 0,		/* changed from 2 to 0 (https://github.com/olikraus/u8g2/issues/1771) */
   /* i2c_bus_clock_100kHz = */ 4,
   /* i2c_bus_clock_100kHz = */ 4,
   /* data_setup_time_ns = */ 100,
   /* data_setup_time_ns = */ 100,
   /* write_pulse_width_ns = */ 100,
   /* write_pulse_width_ns = */ 100,
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -133,12 +133,12 @@ static const u8x8_display_info_t u8x8_ls027b7dh01_400x240_display_info =
   /* sda_setup_time_ns = */ 227,	/* 227 nsec according to the datasheet */		
   /* sda_setup_time_ns = */ 227,	/* 227 nsec according to the datasheet */		
   /* sck_pulse_width_ns = */  255,	/* 450 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 */
   /* 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 */
+  /* spi_mode = */ 0,		/* changed from 2 to 0 (https://github.com/olikraus/u8g2/issues/1771) */
   /* i2c_bus_clock_100kHz = */ 4,
   /* i2c_bus_clock_100kHz = */ 4,
   /* data_setup_time_ns = */ 100,
   /* data_setup_time_ns = */ 100,
   /* write_pulse_width_ns = */ 100,
   /* write_pulse_width_ns = */ 100,
   /* tile_width = */ 50,
   /* tile_width = */ 50,
-  /* tile_hight = */ 30,
+  /* tile_height = */ 30,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 400,
   /* pixel_width = */ 400,
@@ -174,7 +174,7 @@ static const u8x8_display_info_t u8x8_ls027b7dh01_m0_400x240_display_info =
   /* data_setup_time_ns = */ 100,
   /* data_setup_time_ns = */ 100,
   /* write_pulse_width_ns = */ 100,
   /* write_pulse_width_ns = */ 100,
   /* tile_width = */ 50,
   /* tile_width = */ 50,
-  /* tile_hight = */ 30,
+  /* tile_height = */ 30,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 400,
   /* pixel_width = */ 400,
@@ -206,12 +206,12 @@ static const u8x8_display_info_t u8x8_ls013b7dh05_144x168_display_info =
   /* sda_setup_time_ns = */ 227,	/* 227 nsec according to the datasheet */		
   /* sda_setup_time_ns = */ 227,	/* 227 nsec according to the datasheet */		
   /* sck_pulse_width_ns = */  255,	/* 450 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 */
   /* 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 */
+  /* spi_mode = */ 0,		/* changed from 2 to 0 (https://github.com/olikraus/u8g2/issues/1771) */
   /* i2c_bus_clock_100kHz = */ 4,
   /* i2c_bus_clock_100kHz = */ 4,
   /* data_setup_time_ns = */ 100,
   /* data_setup_time_ns = */ 100,
   /* write_pulse_width_ns = */ 100,
   /* write_pulse_width_ns = */ 100,
   /* tile_width = */ 18,
   /* tile_width = */ 18,
-  /* tile_hight = */ 21,
+  /* tile_height = */ 21,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 144,
   /* pixel_width = */ 144,

+ 4 - 4
components/u8g2/u8x8_d_max7219.c

@@ -185,7 +185,7 @@ static const u8x8_display_info_t u8x8_max7219_32x8_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 4,
   /* tile_width = */ 4,
-  /* tile_hight = */ 1,
+  /* tile_height = */ 1,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 32,
   /* pixel_width = */ 32,
@@ -232,7 +232,7 @@ static const u8x8_display_info_t u8x8_max7219_16x16_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 2,
   /* tile_width = */ 2,
-  /* tile_hight = */ 2,
+  /* tile_height = */ 2,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 16,
   /* pixel_width = */ 16,
@@ -287,7 +287,7 @@ static const u8x8_display_info_t u8x8_max7219_8x8_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 1,
   /* tile_width = */ 1,
-  /* tile_hight = */ 1,
+  /* tile_height = */ 1,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 8,
   /* pixel_width = */ 8,
@@ -428,7 +428,7 @@ static const u8x8_display_info_t u8x8_max7219_64x8_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 8,
   /* tile_width = */ 8,
-  /* tile_hight = */ 1,
+  /* tile_height = */ 1,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 64,
   /* pixel_width = */ 64,

+ 1 - 1
components/u8g2/u8x8_d_pcd8544_84x48.c

@@ -91,7 +91,7 @@ static const u8x8_display_info_t u8x8_pcd8544_84x48_display_info =
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
   /* tile_width = */ 11,		/* width of 11*8=88 pixel */
   /* tile_width = */ 11,		/* width of 11*8=88 pixel */
-  /* tile_hight = */ 6,
+  /* tile_height = */ 6,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 84,
   /* pixel_width = */ 84,

+ 1 - 1
components/u8g2/u8x8_d_pcf8812.c

@@ -173,7 +173,7 @@ static const u8x8_display_info_t u8x8_pcf8812_96x65_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 12,
   /* tile_width = */ 12,
-  /* tile_hight = */ 9,
+  /* tile_height = */ 9,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 96,
   /* pixel_width = */ 96,

+ 1 - 1
components/u8g2/u8x8_d_pcf8814_hx1230.c

@@ -178,7 +178,7 @@ static const u8x8_display_info_t u8x8_hx1230_96x68_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 12,
   /* tile_width = */ 12,
-  /* tile_hight = */ 9,
+  /* tile_height = */ 9,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 96,
   /* pixel_width = */ 96,

+ 255 - 0
components/u8g2/u8x8_d_s1d15300.c

@@ -0,0 +1,255 @@
+/*
+
+  u8x8_d_s1d15300.c
+  
+  WARNING: As of today, flip mode 1 doesn't seem to work (see issue 2063)
+  
+  Created as a copy of u8x8_d_st7565.c, see https://github.com/olikraus/u8g2/issues/2063
+  
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2022, 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_s1d15300_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0a4),		                /* all pixel off, see datasheet for the s1d15300 */
+  U8X8_C(0x0af),		                /* display on */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_s1d15300_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0ae),		                /* display off */
+  U8X8_C(0x0a5),		                /* enter powersafe, see datasheet for the s1d15300 */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_s1d15300_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_s1d15300_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 */
+};
+
+uint8_t u8x8_d_s1d15300_common(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));
+    
+      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 st7565 
+	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;
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_s1d15300_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_s1d15300_powersave1_seq);
+      break;
+#ifdef U8X8_WITH_SET_CONTRAST
+    case U8X8_MSG_DISPLAY_SET_CONTRAST:
+      u8x8_cad_StartTransfer(u8x8);
+      u8x8_cad_SendCmd(u8x8, 0x080 |  (arg_int >> 3) ); /* s1d15300 has only 5 bits for contrast */
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+#endif
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+/*================================================*/
+/* LM6023, S1D15300 controller, issue 2063 */
+
+static const u8x8_display_info_t u8x8_s1d15300_lm6023_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 250,	/*  */
+  /* pre_chip_disable_wait_ns = */ 120,	/*  */
+  /* reset_pulse_width_ms = */ 1, 
+  /* post_reset_wait_ms = */ 1, 
+  /* sda_setup_time_ns = */ 200,		/* */
+  /* sck_pulse_width_ns = */ 200,	/* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
+  /* 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,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 200,	/* st7565 datasheet, table 24, tds8 */
+  /* write_pulse_width_ns = */ 200,	/* st7565 datasheet, table 24, tcclw */
+  /* tile_width = */ 16,		/* width of 16*8=128 pixel */
+  /* tile_height = */ 8,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 4,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 64
+};
+
+
+static const uint8_t u8x8_d_s1d15300_lm6023_init_seq[] = {
+
+#ifdef OBSOLETE  
+  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_CA(0x0f8, 0x000),		/* set booster ratio to 4x */
+  U8X8_C(0x025),		                /* set V0 voltage resistor ratio to large,  issue 1678: changed from 0x23 to 0x25 */
+  U8X8_CA(0x081, 170),			/* set contrast, contrast value NHD C12864, see issue 186, increased contrast to 180 (issue 219), reduced to 170 (issue 1678) */
+  
+  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 */
+#endif
+  
+
+    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 normal */
+    U8X8_C(0x0a6), /* Display normal */
+    U8X8_C(0x0a4), /* all point normal */
+
+    U8X8_C(0x0a2), /* LCD bias 1/8 */
+    U8X8_C(0x0c0), /* common output mode */
+    U8X8_C(0x02f), /* all power control circuits on */
+
+
+    U8X8_C(0x090), /* set contrast */
+    //U8X8_C(0x0af), /* display on */
+
+    U8X8_C(0x0b0), /* set page address */
+    U8X8_C(0x01f), /* set column address upper */
+    U8X8_C(0x000), /* set column address lower */
+
+    U8X8_END_TRANSFER(), /* disable chip */
+    U8X8_END()           /* end of sequence */  
+};
+
+uint8_t u8x8_d_s1d15300_lm6023(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  /* call common procedure first and handle messages there */
+  if ( u8x8_d_s1d15300_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_s1d15300_lm6023_display_info);
+	break;
+      case U8X8_MSG_DISPLAY_INIT:
+	u8x8_d_helper_display_init(u8x8);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_s1d15300_lm6023_init_seq);
+	break;
+      case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+	if ( arg_int == 0 )
+	{
+	  u8x8_cad_SendSequence(u8x8, u8x8_d_s1d15300_flip0_seq);
+	  u8x8->x_offset = u8x8->display_info->default_x_offset;
+	}
+	else
+	{
+	  u8x8_cad_SendSequence(u8x8, u8x8_d_s1d15300_flip1_seq);
+	  u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+	}	
+	break;
+      default:
+	return 0;		/* msg unknown */
+    }
+  }
+  return 1;
+}
+
+/*================================================*/
+
+

+ 5 - 1
components/u8g2/u8x8_d_s1d15721.c

@@ -87,6 +87,10 @@ uint8_t u8x8_d_s1d15721_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
       u8x8_cad_SendCmd(u8x8, 0x13);	/* col */
       u8x8_cad_SendCmd(u8x8, 0x13);	/* col */
       u8x8_cad_SendArg(u8x8, x);
       u8x8_cad_SendArg(u8x8, x);
 
 
+      /* 4 Mar 2022: added the missing page address, issue 1802 */
+      u8x8_cad_SendCmd(u8x8, 0xb1);	/* page address */
+      u8x8_cad_SendArg(u8x8, y);
+
 	  u8x8_cad_SendCmd(u8x8, 0x1D );	//Data Write
 	  u8x8_cad_SendCmd(u8x8, 0x1D );	//Data Write
 
 
       c = ((u8x8_tile_t *)arg_ptr)->cnt;
       c = ((u8x8_tile_t *)arg_ptr)->cnt;
@@ -157,7 +161,7 @@ static const u8x8_display_info_t u8x8_s1d15721_240x64_display_info =
   /* data_setup_time_ns = */ 30,	         /*  */
   /* data_setup_time_ns = */ 30,	         /*  */
   /* write_pulse_width_ns = */ 65,	/* */
   /* write_pulse_width_ns = */ 65,	/* */
   /* tile_width = */ 30,		                /* width of 20*8=160 pixel (30*8 = 240) */
   /* tile_width = */ 30,		                /* width of 20*8=160 pixel (30*8 = 240) */
-  /* tile_hight = */ 8,                 /* height 8*8 = 64*/
+  /* tile_height = */ 8,                 /* height 8*8 = 64*/
   /* default_x_offset = */ 1,	
   /* default_x_offset = */ 1,	
   /* flipmode_x_offset = */ 1,	
   /* flipmode_x_offset = */ 1,	
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,

+ 1 - 1
components/u8g2/u8x8_d_s1d15e06.c

@@ -157,7 +157,7 @@ static const u8x8_display_info_t u8x8_s1d15e06_160100_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 65,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 65,	/* uc1608 datasheet, page 39 */
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
-  /* tile_hight = */ 13,
+  /* tile_height = */ 13,
   /* default_x_offset = */ 0,	/* reused as y page offset */
   /* default_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,

+ 1 - 1
components/u8g2/u8x8_d_sbn1661.c

@@ -128,7 +128,7 @@ static const u8x8_display_info_t u8x8_sbn1661_122x32_display_info =
   /* data_setup_time_ns = */ 200,
   /* data_setup_time_ns = */ 200,
   /* write_pulse_width_ns = */ 200,	/*  */
   /* write_pulse_width_ns = */ 200,	/*  */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 122,
   /* pixel_width = */ 122,

+ 185 - 2
components/u8g2/u8x8_d_sed1330.c

@@ -141,7 +141,7 @@ static const u8x8_display_info_t u8x8_sed1330_240x128_display_info =
   /* data_setup_time_ns = */ 120,		/* G242CX Datasheet p5 */
   /* data_setup_time_ns = */ 120,		/* G242CX Datasheet p5 */
   /* write_pulse_width_ns = */ 220,		/* G242CX Datasheet p5 */
   /* write_pulse_width_ns = */ 220,		/* G242CX Datasheet p5 */
   /* tile_width = */ 0x01e,
   /* tile_width = */ 0x01e,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -286,7 +286,7 @@ static const u8x8_display_info_t u8x8_sed1330_320x240_display_info =
   /* data_setup_time_ns = */ 120,		/* G242CX Datasheet p5 */
   /* data_setup_time_ns = */ 120,		/* G242CX Datasheet p5 */
   /* write_pulse_width_ns = */ 220,		/* G242CX Datasheet p5 */
   /* write_pulse_width_ns = */ 220,		/* G242CX Datasheet p5 */
   /* tile_width = */ 40,
   /* tile_width = */ 40,
-  /* tile_hight = */ 30,
+  /* tile_height = */ 30,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 320,
   /* pixel_width = */ 320,
@@ -349,3 +349,186 @@ uint8_t u8x8_d_ra8835_320x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
   }
   }
   return 1;
   return 1;
 }
 }
+
+/*=============================================*/
+/*
+https://github.com/olikraus/u8g2/issues/1908
+https://www.allelectronics.com/mas_assets/media/allelectronics2018/spec/LCD-101.pdf
+*/
+
+static const u8x8_display_info_t u8x8_sed1330_256x128_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 = */ 32,
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 256,
+  /* pixel_height = */ 128
+};
+
+
+/* 256x128 Hyundai HG25604  (HG25504???) */
+static const uint8_t u8x8_d_sed1330_256x128_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(0x01f),		/* 32-1*/  /* 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(0x020),		/* 32 */	/* 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, 11 Bytes in total */
+  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),
+};
+
+uint8_t u8x8_d_sed1330_256x128(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_256x128_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_256x128_init_seq);
+      break;
+    default:
+      return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+
+
+
+
+
+
+
+/*=============================================*/
+
+/*
+https://github.com/olikraus/u8g2/issues/1086
+*/
+
+static const u8x8_display_info_t u8x8_sed1330_320x200_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_height = */ 25,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 320,
+  /* pixel_height = */ 200
+};
+
+static const uint8_t u8x8_d_sed1330_320x200_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(0x02F),				/* TC/R: According to app notes fOSC=6Mhz fFF=70Hz --> TC/R = 74d*/
+  U8X8_A(0x0c7),				/* 0xc7=199, 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(0x000),				/* High byte of the virtual screen size, see also section 9.1.2 */
+	
+  U8X8_C(0x044),				/* SCROLL, 11 Bytes in total */
+  U8X8_A(0x000),				/* Screen 1 Start Address (Low) = 00H */
+  U8X8_A(0x000),				/* Screen 1 Start Address (High) = 00H */
+  U8X8_A(0x0c7),                                /* Screen Layer 1 Number of lines = 200d */ 
+  U8X8_A(0x0b0),                                /* Screen 2 Start Address (Low) = 00H */
+  U8X8_A(0x005),                                /* Screen 2 Start Address (High) = 00H */
+  U8X8_A(0x0c7),                                /* Screen Layer 2 Number of lines = 200d */
+  U8X8_C(0x04C),                                /* Cursor Direction 0,0 Shift Direction = Right */
+  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_sed1330_320x200(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_320x200_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_320x200_init_seq);
+      break;
+    default:
+      return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+
+

+ 1 - 1
components/u8g2/u8x8_d_sh1106_64x32.c

@@ -189,7 +189,7 @@ static const u8x8_display_info_t u8x8_sh1106_64x32_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 8,
   /* tile_width = */ 8,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 32,
   /* default_x_offset = */ 32,
   /* flipmode_x_offset = */ 36,
   /* flipmode_x_offset = */ 36,
   /* pixel_width = */ 64,
   /* pixel_width = */ 64,

+ 1 - 1
components/u8g2/u8x8_d_sh1106_72x40.c

@@ -189,7 +189,7 @@ static const u8x8_display_info_t u8x8_sh1106_72x40_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 9,
   /* tile_width = */ 9,
-  /* tile_hight = */ 5,
+  /* tile_height = */ 5,
   /* default_x_offset = */ 30,
   /* default_x_offset = */ 30,
   /* flipmode_x_offset = */ 30,
   /* flipmode_x_offset = */ 30,
   /* pixel_width = */ 72,
   /* pixel_width = */ 72,

+ 313 - 5
components/u8g2/u8x8_d_sh1107.c

@@ -70,6 +70,87 @@ static const uint8_t u8x8_d_sh1107_64x128_noname_flip1_seq[] = {
   U8X8_END()             			/* end of sequence */
   U8X8_END()             			/* end of sequence */
 };
 };
 
 
+static uint8_t u8x8_d_sh1107_HJR_OEL1M0201_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 | (2+(((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 uint8_t u8x8_d_sh1107_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 static uint8_t u8x8_d_sh1107_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
 {
@@ -288,7 +369,7 @@ static const u8x8_display_info_t u8x8_sh1107_seeed_96x96_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 12,
   /* tile_width = */ 12,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 96,
   /* pixel_width = */ 96,
@@ -317,6 +398,70 @@ uint8_t u8x8_d_sh1107_seeed_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, vo
 }
 }
 
 
 
 
+
+
+static const uint8_t u8x8_d_sh1107_HJR_OEL1M0201_96x96_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+
+	U8X8_C(0xAE),//
+	
+	U8X8_C(0x0F),//
+	U8X8_C(0x17),//
+	
+	
+	U8X8_C(0xD9),//
+	U8X8_C(0x89), //
+	
+  U8X8_CA(0x0d3, 0x000),		/* display offset */
+  U8X8_CA(0x0dc, 0x070),		/* start line */
+	
+  U8X8_C(0x0a0),				/* segment remap a0/a1 A0��??A1?���?a|��1D����*/
+  U8X8_C(0x0c0),				/* c0: scan dir normal, c8: reverse */
+	
+	U8X8_C(0xD5),//
+	U8X8_C(0xB0),//
+	
+	U8X8_C(0x20),//
+	
+	U8X8_C(0xDB),//
+	U8X8_C(0x35),//
+	
+	U8X8_C(0x81),//
+	
+	U8X8_C(0xC7),//
+	
+	U8X8_C(0xA4),//A5����????��
+	
+	U8X8_C(0xA6),//A6��??A7?���?a?��??��|?
+	
+	U8X8_C(0xAD),//
+	U8X8_C(0x80),//
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+uint8_t u8x8_d_sh1107_hjr_oel1m0201_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{ 
+  if ( u8x8_d_sh1107_HJR_OEL1M0201_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_HJR_OEL1M0201_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 */
 /* 128x128 OLED: this display has a very strange x offset */
 
 
@@ -370,7 +515,7 @@ static const u8x8_display_info_t u8x8_sh1107_128x128_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 96,
   /* default_x_offset = */ 96,
   /* flipmode_x_offset = */ 96,
   /* flipmode_x_offset = */ 96,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -421,7 +566,7 @@ static const u8x8_display_info_t u8x8_sh1107_128x80_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 10,
   /* tile_width = */ 10,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 24,
   /* default_x_offset = */ 24,
   /* flipmode_x_offset = */ 24,
   /* flipmode_x_offset = */ 24,
   /* pixel_width = */ 80,
   /* pixel_width = */ 80,
@@ -469,7 +614,7 @@ static const u8x8_display_info_t u8x8_sh1107_pimoroni_128x128_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -523,7 +668,7 @@ static const u8x8_display_info_t u8x8_seeed_128x128_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -550,3 +695,166 @@ uint8_t u8x8_d_sh1107_seeed_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
   }
   }
   return 1;
   return 1;
 }
 }
+static const uint8_t u8x8_d_sh1107_80x128_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0xAE), /*display off*/
+	U8X8_C(0x00), /*set lower column address*/
+	U8X8_C(0x10), /*set higher column address*/
+	U8X8_C(0x20), /* Set Memory addressing mode (0x20/0x21) */
+	U8X8_C(0x81), /*contract control*/
+	U8X8_C(0x6f), /*b0*/
+	U8X8_C(0xA0), /*set segment remap*/
+	U8X8_C(0xC0), /*Com scan direction*/
+	U8X8_C(0xA4), /*Disable Entire Display On (0xA4/0xA5)*/
+	U8X8_C(0xA6), /*normal / reverse*/
+	U8X8_C(0xD5), /*set osc division*/
+	U8X8_C(0x91),
+	U8X8_C(0xD9), /*set pre-charge period*/
+	U8X8_C(0x22),
+	U8X8_C(0xdb), /*set vcomh*/
+	U8X8_C(0x3f),
+	U8X8_C(0xA8), /*multiplex ratio*/
+	U8X8_C(0x4F), /*duty = 1/80*/
+	U8X8_C(0xD3), /*set display offset*/
+	U8X8_C(0x68), /*18*/
+	U8X8_C(0xdc), /*Set Display Start Line*/
+	U8X8_C(0x00),
+	U8X8_C(0xad), /*set charge pump enable*/
+	U8X8_C(0x8a), /*Set DC-DC enable (a=0:disable, a=1:enable) */
+//	OLED_Clear(),
+	U8X8_C(0xAF), /*display ON*/ 
+ 
+
+
+  //U8X8_CA(0x0dc, 0x000),		/* start line */
+ // U8X8_CA(0x081, 0x02f), 		/* [2] set contrast control */
+
+
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+static uint8_t u8x8_d_sh1107_TK078F288_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;
+}
+static const u8x8_display_info_t u8x8_TK078F288_80x128_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 = */ 2,		// 400kHz does not work, but 200kHz seems to be ok
+  /* data_setup_time_ns = */ 40,
+  /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 10,
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 80,
+  /* pixel_height = */ 128
+};
+uint8_t u8x8_d_sh1107_tk078f288_80x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    
+  if ( u8x8_d_sh1107_TK078F288_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_80x128_init_seq); 
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_TK078F288_80x128_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}

+ 74 - 0
components/u8g2/u8x8_d_sh1108.c

@@ -223,3 +223,77 @@ uint8_t u8x8_d_sh1108_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
 }
 }
 
 
 /*==================================================*/
 /*==================================================*/
+
+
+/* issue #1998, 128x160 OLED */
+static const uint8_t u8x8_d_sh1108_128x160_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),		                /* 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_128x160_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 = */ 16,
+  /* tile_height = */ 20,
+  /* default_x_offset = */ 16,
+  /* flipmode_x_offset = */ 16,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 160
+};
+
+uint8_t u8x8_d_sh1108_128x160(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_128x160_noname_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sh1108_128x160_noname_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+/*==================================================*/

+ 7 - 4
components/u8g2/u8x8_d_sh1122.c

@@ -32,8 +32,11 @@
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 
 
 
 
-  Copied from sh1122 mostly because of the similar RAM architecture.
-  However: Commands are very different!
+  Idea: SH1122 is a horizontal device, which doesn't support u8x8
+  However in the similar SSD1362 device, we do the correct tile conversion,
+    so maybe takeover code from SSD1362 to SH1122, so that SH1122 can also
+    support u8x8
+
   
   
 */
 */
 #include "u8x8.h"
 #include "u8x8.h"
@@ -147,7 +150,7 @@ uint8_t u8x8_d_sh1122_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
     case U8X8_MSG_DISPLAY_DRAW_TILE:
     case U8X8_MSG_DISPLAY_DRAW_TILE:
       u8x8_cad_StartTransfer(u8x8);
       u8x8_cad_StartTransfer(u8x8);
       x = ((u8x8_tile_t *)arg_ptr)->x_pos;    
       x = ((u8x8_tile_t *)arg_ptr)->x_pos;    
-      x *= 2;		// only every 4th col can be addressed
+      x *= 2;		// 4 Mar 2022: probably this needs to be 4, but this device is call with x=0 only
       x += u8x8->x_offset;		
       x += u8x8->x_offset;		
     
     
       y = (((u8x8_tile_t *)arg_ptr)->y_pos);
       y = (((u8x8_tile_t *)arg_ptr)->y_pos);
@@ -219,7 +222,7 @@ static const u8x8_display_info_t u8x8_sh1122_256x64_display_info =
   /* data_setup_time_ns = */ 10,
   /* data_setup_time_ns = */ 10,
   /* write_pulse_width_ns = */ 150,	/* sh1122: cycle time is 300ns, so use 300/2 = 150 */
   /* 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_width = */ 32,		/* 256 pixel, so we require 32 bytes for this */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* default_x_offset = */ 0,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,

+ 68 - 4
components/u8g2/u8x8_d_ssd1305.c

@@ -148,7 +148,7 @@ static const u8x8_display_info_t u8x8_ssd1305_128x32_noname_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 2,
   /* default_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -224,6 +224,70 @@ uint8_t u8x8_d_ssd1305_128x32_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
   return 1;
   return 1;
 }
 }
 
 
+/*================================================*/
+/* issue 2002: Waveshare */
+
+#ifdef SAME_AS_ADAFRUIT
+/* timing from SSD1306 */
+static const u8x8_display_info_t u8x8_ssd1305_128x32_waveshare_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_height = */ 4,
+  /* default_x_offset = */ 4,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 32
+};
+
+uint8_t u8x8_d_ssd1305_128x32_waveshare(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_waveshare_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+#endif
+
+
 /*================================================*/
 /*================================================*/
 /* adafruit 128x32 SSD1305 OLED, https://www.adafruit.com/product/2675 */
 /* adafruit 128x32 SSD1305 OLED, https://www.adafruit.com/product/2675 */
 /* issue 724 */
 /* issue 724 */
@@ -246,7 +310,7 @@ static const u8x8_display_info_t u8x8_ssd1305_128x32_adafruit_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 4,
   /* default_x_offset = */ 4,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -311,7 +375,7 @@ static const u8x8_display_info_t u8x8_ssd1305_128x64_adafruit_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 2,
   /* default_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -409,7 +473,7 @@ static const u8x8_display_info_t u8x8_ssd1305_128x64_raystar_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 4,
   /* default_x_offset = */ 4,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 3 - 3
components/u8g2/u8x8_d_ssd1306_128x32.c

@@ -194,7 +194,7 @@ static const u8x8_display_info_t u8x8_ssd1306_128x32_univision_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -234,7 +234,7 @@ static const u8x8_display_info_t u8x8_ssd1306_128x32_winstar_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 125,
   /* default_x_offset = */ 125,
   /* flipmode_x_offset = */ 125,
   /* flipmode_x_offset = */ 125,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -297,7 +297,7 @@ static const u8x8_display_info_t u8x8_d_sh1106_128x32_visionox_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 2,
   /* default_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 82 - 3
components/u8g2/u8x8_d_ssd1306_128x64_noname.c

@@ -172,6 +172,38 @@ static const uint8_t u8x8_d_sh1106_128x64_winstar_init_seq[] = {
   U8X8_END()             			/* end of sequence */
   U8X8_END()             			/* end of sequence */
 };
 };
 
 
+static const uint8_t u8x8_d_ssd1312_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),		/* horizontal addressing mode */
+  
+  U8X8_C(0x0a1),				/* 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_ssd1306_128x64_noname_powersave0_seq[] = {
 static const uint8_t u8x8_d_ssd1306_128x64_noname_powersave0_seq[] = {
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
@@ -203,6 +235,21 @@ static const uint8_t u8x8_d_ssd1306_128x64_noname_flip1_seq[] = {
   U8X8_END()             			/* end of sequence */
   U8X8_END()             			/* end of sequence */
 };
 };
 
 
+static const uint8_t u8x8_d_ssd1312_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(0x0c0),				/* c0: scan dir normal, c8: reverse */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1312_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(0x0c8),				/* 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)
 static uint8_t u8x8_d_ssd1306_sh1106_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
 {
@@ -302,7 +349,7 @@ static const u8x8_display_info_t u8x8_ssd1306_128x64_noname_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -330,6 +377,38 @@ uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
   return 1;
   return 1;
 }
 }
 
 
+uint8_t u8x8_d_ssd1312_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x64_noname_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x64_noname_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_ssd1312_128x64_noname_init_seq);    /* update 27 mar 2022 */
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
+      break;
+    default:
+      if ( u8x8_d_ssd1306_sh1106_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+        return 1;
+  }
+  return 1;
+}
+
+
+
 uint8_t u8x8_d_ssd1306_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 uint8_t u8x8_d_ssd1306_128x64_vcomh0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
 {
     
     
@@ -385,12 +464,12 @@ static const u8x8_display_info_t u8x8_sh1106_128x64_noname_display_info =
   /* sda_setup_time_ns = */ 50,		/* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
   /* 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_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) */
   /* 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 */
+  /* spi_mode = */ 0,		/* issue 1901: changed mode from 3 to 0 */
   /* i2c_bus_clock_100kHz = */ 4,
   /* i2c_bus_clock_100kHz = */ 4,
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 2,
   /* default_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 1 - 1
components/u8g2/u8x8_d_ssd1306_64x32.c

@@ -155,7 +155,7 @@ static const u8x8_display_info_t u8x8_ssd1306_64x32_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 8,
   /* tile_width = */ 8,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 32,
   /* default_x_offset = */ 32,
   /* flipmode_x_offset = */ 32,
   /* flipmode_x_offset = */ 32,
   /* pixel_width = */ 64,
   /* pixel_width = */ 64,

+ 1 - 1
components/u8g2/u8x8_d_ssd1306_64x48.c

@@ -186,7 +186,7 @@ static const u8x8_display_info_t u8x8_ssd1306_64x48_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 8,
   /* tile_width = */ 8,
-  /* tile_hight = */ 6,
+  /* tile_height = */ 6,
   /* default_x_offset = */ 32,
   /* default_x_offset = */ 32,
   /* flipmode_x_offset = */ 32,
   /* flipmode_x_offset = */ 32,
   /* pixel_width = */ 64,
   /* pixel_width = */ 64,

+ 1 - 1
components/u8g2/u8x8_d_ssd1306_72x40.c

@@ -236,7 +236,7 @@ static const u8x8_display_info_t u8x8_ssd1306_72x40_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 9,
   /* tile_width = */ 9,
-  /* tile_hight = */ 5,
+  /* tile_height = */ 5,
   /* default_x_offset = */ 28,
   /* default_x_offset = */ 28,
   /* flipmode_x_offset = */ 28,
   /* flipmode_x_offset = */ 28,
   /* pixel_width = */ 72,
   /* pixel_width = */ 72,

+ 1 - 1
components/u8g2/u8x8_d_ssd1306_96x16.c

@@ -186,7 +186,7 @@ static const u8x8_display_info_t u8x8_ssd1306_96x16_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 12,
   /* tile_width = */ 12,
-  /* tile_hight = */ 2,
+  /* tile_height = */ 2,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 32,
   /* flipmode_x_offset = */ 32,
   /* pixel_width = */ 96,
   /* pixel_width = */ 96,

+ 328 - 0
components/u8g2/u8x8_d_ssd1306_96x40.c

@@ -0,0 +1,328 @@
+/*
+
+  u8x8_d_ssd1306_96x40.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.  
+  
+  takeover from 96x16 OLED
+  
+  21 Sep 2022: Also added the 96x39 variant here....
+  
+*/
+
+
+#include "u8x8.h"
+
+
+
+static const uint8_t u8x8_d_ssd1306_96x40_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_96x40_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_96x40_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_96x40_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_96x40_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_96x40_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x40_er_init_seq);    
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x40_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x40_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x40_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x40_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;
+}
+
+/*===============================================*/
+
+/* https://github.com/olikraus/u8g2/issues/1812 */
+static const uint8_t u8x8_d_ssd1306_96x40_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 */
+  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, 0.66 OLED  0x14*/
+  U8X8_CA(0x020, 0x000),		/* horizontal 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 */
+  U8X8_CA(0x0d9, 0x0f1),		/* [2] pre-charge period 0x0f1 */
+  U8X8_CA(0x0db, 0x020),		/* 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 u8x8_display_info_t u8x8_ssd1306_96x40_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_height = */ 5,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 32,
+  /* pixel_width = */ 96,
+  /* pixel_height = */ 40
+};
+
+uint8_t u8x8_d_ssd1306_96x40(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_96x40_display_info);
+      return 1;
+    }
+    else if ( msg == U8X8_MSG_DISPLAY_INIT )
+    {
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x40_init_seq);    
+      return 1;
+    }
+    return u8x8_d_ssd1306_96x40_generic(u8x8, msg, arg_int, arg_ptr);
+}
+
+/*===============================================*/
+
+/* 96x39 OLED */
+/* https://github.com/olikraus/u8g2/issues/1959 */
+static const uint8_t u8x8_d_ssd1306_96x39_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 */
+  U8X8_CA(0x0d3, 0),		        /* display offset, issue 1959 */
+  U8X8_C(0x040),		                /* set display start line to 0 */
+  U8X8_CA(0x08d, 0x014),		/* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, 0.66 OLED  0x14*/
+  U8X8_CA(0x020, 0x000),		/* horizontal 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, 0x010),		/* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5), issue 1959: 0x010 */
+  U8X8_CA(0x081, 0x0af),		/* [2] set contrast control */
+  U8X8_CA(0x0d9, 0x0f1),		/* [2] pre-charge period 0x0f1 */
+  U8X8_CA(0x0db, 0x020),		/* 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_96x39_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_C(0x07f),		                /* set display start line to -1 (not exactly sure why...) */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1306_96x39_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_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_ssd1306_96x39_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_height = */ 5,
+  /* default_x_offset = */ 32,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 96,
+  /* pixel_height = */ 39
+};
+
+uint8_t u8x8_d_ssd1306_96x39(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_96x39_display_info);
+      return 1;
+    }
+    else if ( msg == U8X8_MSG_DISPLAY_INIT )
+    {
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x39_init_seq);    
+      return 1;
+    }
+    else if ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
+    {
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x39_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_96x39_flip1_seq);
+	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+    }
+    return u8x8_d_ssd1306_96x40_generic(u8x8, msg, arg_int, arg_ptr);
+}
+
+/*===============================================*/
+

+ 3 - 3
components/u8g2/u8x8_d_ssd1309.c

@@ -148,7 +148,7 @@ static const u8x8_display_info_t u8x8_ssd1309_128x64_noname2_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 2,
   /* default_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* flipmode_x_offset = */ 2,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -247,7 +247,7 @@ static const u8x8_display_info_t u8x8_ssd1309_128x64_noname0_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -335,7 +335,7 @@ static const u8x8_display_info_t u8x8_ssd1309_102x64_ea_oleds102_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 13,  /* width of 13*8=104 pixel */
   /* tile_width = */ 13,  /* width of 13*8=104 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 13, 
   /* default_x_offset = */ 13, 
   /* flipmode_x_offset = */ 13,
   /* flipmode_x_offset = */ 13,
   /* pixel_width = */ 102,
   /* pixel_width = */ 102,

+ 97 - 1
components/u8g2/u8x8_d_ssd1316.c

@@ -207,7 +207,7 @@ static const u8x8_display_info_t u8x8_ssd1316_128x32_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -234,3 +234,99 @@ uint8_t u8x8_d_ssd1316_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
   }
   }
   return 1;
   return 1;
 }
 }
+
+
+/*===================================================*/
+/*
+QG-9632TLBZG02
+https://datasheet.lcsc.com/lcsc/1804162033_Shenzhen-Allvision-Tech-QG-9632TLBZG02_C91216.pdf
+https://github.com/olikraus/u8g2/issues/1938
+
+96x32
+*/
+
+static const uint8_t u8x8_d_ssd1316_96x32_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  
+  U8X8_C(0x0ae),		        /* display off */
+  U8X8_C(0x040),		        /* start line */
+  U8X8_CA(0x081, 0x045), 		/* QG-2832TSWZG02 datasheet: 0x081, 0x45 */
+                                                        /* QG-9632: 0x81, 0x60 */
+
+  U8X8_C(0x0a6),			/* none inverted normal display mode */
+  U8X8_CA(0x0a8, 0x01f),		/* multiplex ratio, duty = 1/32 */
+
+  U8X8_C(0x0a1),			/* segment remap a0/a1*/
+  U8X8_C(0x0c0),			/* c0: scan dir normal, c8: reverse */
+
+  U8X8_CA(0x0d3, 0x000),		/* display offset */
+  U8X8_CA(0x0d5, 0x080),		/* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
+  U8X8_CA(0x0d9, 0x022), 		/* [2] pre-charge period 0x022/f1*/
+  U8X8_CA(0x0da, 0x012),		/* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
+  U8X8_CA(0x0db, 0x020), 		/* vcomh deselect level */  
+  U8X8_CA(0x08d, 0x015),		/* [2] charge pump setting (p62): 0x014 enable, 0x010 disable, */
+                                                        /* QG-9632: 0x8d, 0x10 */
+  
+  //U8X8_CA(0x0a2, 0x000),		/* set display start line to 0 */
+  //U8X8_CA(0x020, 0x000),		/* horizontal addressing mode */
+  
+  
+  // Flipmode
+  //U8X8_C(0x0a1),			/* segment remap a0/a1*/
+  //U8X8_C(0x0c0),			/* c0: scan dir normal, c8: reverse */
+  
+  U8X8_C(0x02e),			/* Deactivate scroll */ 
+  //U8X8_C(0x0a4),			/* output ram to display */
+    
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()           			/* end of sequence */
+};
+
+
+static const u8x8_display_info_t u8x8_ssd1316_96x32_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, 	/* reset time */
+  /* post_reset_wait_ms = */ 100, /* reset delay */
+  /* 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_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 96,
+  /* pixel_height = */ 32
+};
+
+uint8_t u8x8_d_ssd1316_96x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    
+  if ( u8x8_d_ssd1316_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_ssd1316_96x32_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1316_96x32_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+

+ 1 - 1
components/u8g2/u8x8_d_ssd1317.c

@@ -212,7 +212,7 @@ static const u8x8_display_info_t u8x8_ssd1317_96x96_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 12,
   /* tile_width = */ 12,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 16,
   /* default_x_offset = */ 16,
   /* flipmode_x_offset = */ 16,
   /* flipmode_x_offset = */ 16,
   /* pixel_width = */ 96,
   /* pixel_width = */ 96,

+ 1 - 1
components/u8g2/u8x8_d_ssd1318.c

@@ -267,7 +267,7 @@ static const u8x8_display_info_t u8x8_ssd1318_128x96_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 266 - 38
components/u8g2/u8x8_d_ssd1320.c

@@ -40,7 +40,10 @@
   Adapted from u8x8_d_ssd1322.c with the command set of the SSD1320 controller
   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
   "official" procedure is described here: https://github.com/olikraus/u8g2/wiki/internal
   
   
-  NOTE: U8x8 does NOT work!
+  NOTE: U8x8 does NOT work! --> not clear, needs to be checked
+  
+  
+  https://github.com/olikraus/u8g2/issues/1816
   
   
 */
 */
 
 
@@ -67,12 +70,12 @@ static const uint8_t u8x8_d_ssd1320_cs1_160x132_nhd_powersave1_seq[] = {
   output:
   output:
     Tile for SSD1320 (32 Bytes)
     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_to32_dest_buf[32];
 
 
+
+
 static uint8_t *u8x8_ssd1320_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
 static uint8_t *u8x8_ssd1320_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
 {
 {
   uint8_t v;
   uint8_t v;
@@ -98,12 +101,10 @@ static uint8_t *u8x8_ssd1320_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
       a >>= 1;
       a >>= 1;
       b >>= 1;
       b >>= 1;
     }
     }
-  }
-  
+  }  
   return u8x8_ssd1320_to32_dest_buf;
   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 u8x8_d_ssd1320_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
 {
   uint8_t x; 
   uint8_t x; 
@@ -178,6 +179,113 @@ uint8_t u8x8_d_ssd1320_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
   return 1;
   return 1;
 }
 }
 
 
+
+
+
+static uint8_t *u8x8_ssd1320_8to32_2(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 |= 0xf0;     // changed from 0x0f to 0xf0, https://github.com/olikraus/u8g2/issues/1816
+      if ( b&1 ) v |= 0x0f;     // changed from 0xf0 to 0x0f, https://github.com/olikraus/u8g2/issues/1816
+      *dest = v;
+      dest+=4;
+      a >>= 1;
+      b >>= 1;
+    }
+  }
+  return u8x8_ssd1320_to32_dest_buf;
+}
+
+uint8_t u8x8_d_ssd1320_common_2(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_2(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;
+}
+
+
 /*=========================================================*/
 /*=========================================================*/
 /* 160x32 */
 /* 160x32 */
 
 
@@ -212,7 +320,7 @@ static const u8x8_display_info_t u8x8_d_ssd1320_cs1_160x32_display_info =
   /* data_setup_time_ns = */ 10,
   /* data_setup_time_ns = */ 10,
   /* write_pulse_width_ns = */ 150,	/* ssd1320: cycle time is 300ns, so use 300/2 = 150 */
   /* 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_width = */ 20,		/* 160 pixel, so we require 20 bytes for this */
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* default_x_offset = */ 0,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,
@@ -327,7 +435,7 @@ static const u8x8_display_info_t u8x8_d_ssd1320_cs1_160x132_display_info =
   /* data_setup_time_ns = */ 10,
   /* data_setup_time_ns = */ 10,
   /* write_pulse_width_ns = */ 150,	/* ssd1320: cycle time is 300ns, so use 300/2 = 150 */
   /* 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_width = */ 20,		/* 160 pixel, so we require 20 bytes for this */
-  /* tile_hight = */ 17,
+  /* tile_height = */ 17,
   /* default_x_offset = */ 0,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* default_x_offset = */ 0,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,
@@ -336,42 +444,45 @@ static const u8x8_display_info_t u8x8_d_ssd1320_cs1_160x132_display_info =
 
 
 
 
 /* the following sequence will work, but requires contrast to be very high */
 /* the following sequence will work, but requires contrast to be very high */
-// static const uint8_t u8x8_d_ssd1320_cs1_160x132_init_seq[] = {
+/* added #ifdef to avoid compiler warning, issue 1802 */
+#ifdef NOT_USED
+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_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, 0x83),			/* multiplex ratio 1/132 Duty  */  
-//     U8X8_CA(0xa2, 0x00),			/* display start line */  
+    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, 0x83),			/* multiplex ratio 1/132 Duty  */  
+    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(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_C(0xc8),	             /* Set COM Output Scan Direction: normal mode CS1 */
+    // U8X8_C(0xc0),			        /* Set COM Output Scan Direction: normal mode CS2 */
   
   
-//     U8X8_CA(0xd3, 0x0e),        /* CS1 */
-//     // U8X8_CA(0xd3, 0x92),        /* CS2 */
+    U8X8_CA(0xd3, 0x0e),        /* 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 */
-// };
+    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 */
+};
+#endif
 
 
 /*
 /*
 OLED_WR_Byte(0xae,OLED_CMD);//Display OFF
 OLED_WR_Byte(0xae,OLED_CMD);//Display OFF
@@ -492,3 +603,120 @@ uint8_t u8x8_d_ssd1320_160x132(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
   return 1;
   return 1;
 }
 }
 
 
+
+
+
+/*=========================================================*/
+/* https://github.com/olikraus/u8g2/issues/1816 */
+/* 160x80, https://de.aliexpress.com/item/1005003510267760.html */
+
+static const uint8_t u8x8_d_ssd1320_160x80_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0a0),		/* remap */
+  U8X8_C(0xc8),	             /* Set COM Output Scan Direction: normal mode CS1 */
+  U8X8_CA(0xd3, 39),        /* display offset */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1320_160x80_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0a1),		/* remap */
+  U8X8_C(0xc0),	             /* Set COM Output Scan Direction: normal mode CS1 */
+  U8X8_CA(0xd3, 120),        /* display offset */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const u8x8_display_info_t u8x8_d_ssd1320_160x80_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_height = */ 10,
+  /* 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 = */ 80
+};
+
+
+
+static const uint8_t u8x8_d_ssd1320_160x80_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(0xa8, 80),	/* multiplex ratio 1/80 Duty  */  
+    U8X8_CA(0xa2, 0),	/* display start line */  
+
+    U8X8_C(0xa0),	                /* Set Segment Re-Map */
+    U8X8_C(0xc8),	             	/* Set COM Output Scan Direction: normal mode */
+
+    U8X8_CA(0xad, 0x10), 		/* select Iref: 0x00 external (reset default), 0x10 internal */
+    U8X8_CA(0xbc, 0x1e), 		/* pre-charge voltage level 0x00..0x1f, reset default: 0x1e */
+    U8X8_C(0xbf),		        	/* select linear LUT */  
+    U8X8_CA(0xd5, 0xc2), 		/* Bit 0..3: clock ratio 1, 2, 4, 8, ...256, reset=0x1, Bit 4..7: F_osc 0..15 */
+    U8X8_CA(0xd9, 0x72),		/* Set Phase 1&2 Length, Bit 0..3: Phase 1, Bit 4..7: Phase 2, reset default 0x72 */  
+
+    U8X8_CA(0xd3, 39),        /* display offset */
+    
+    U8X8_CA(0xda, 0x12),	/* Set SEG Pins Hardware Configuration:  */  
+    U8X8_CA(0x81, 0x70),			/* contrast */  
+    U8X8_CA(0x20, 0x00),	    /* Memory Addressing Mode: Horizontal */  
+    
+    U8X8_C(0xa4),		        	/* display RAM 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_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  
+  if ( u8x8_d_ssd1320_common_2(u8x8, msg, arg_int, arg_ptr) != 0 )
+    return 1;
+
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+        u8x8_d_helper_display_setup_memory(u8x8, &u8x8_d_ssd1320_160x80_display_info);
+      break;
+
+    case U8X8_MSG_DISPLAY_INIT:
+        u8x8_d_helper_display_init(u8x8);
+        u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_160x80_init_seq);
+      break;
+
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 ){
+        u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_160x80_flip0_seq);
+        u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else{
+        u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_160x80_flip1_seq);
+        u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+    
+    default:
+      break;
+  }
+  return 1;
+}

+ 122 - 2
components/u8g2/u8x8_d_ssd1322.c

@@ -256,7 +256,7 @@ static const u8x8_display_info_t u8x8_ssd1322_256x64_display_info =
   /* data_setup_time_ns = */ 10,
   /* data_setup_time_ns = */ 10,
   /* write_pulse_width_ns = */ 150,	/* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
   /* 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_width = */ 32,		/* 256 pixel, so we require 32 bytes for this */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0x01c,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* default_x_offset = */ 0x01c,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* flipmode_x_offset = */ 0x01c,
   /* flipmode_x_offset = */ 0x01c,
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,
@@ -330,6 +330,103 @@ uint8_t u8x8_d_ssd1322_nhd_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, vo
   return 1;
   return 1;
 }
 }
 
 
+/*=========================================================*/
+/*
+https://github.com/olikraus/u8g2/issues/2092
+*/
+
+
+static const u8x8_display_info_t u8x8_ssd1322_240x128_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 = */ 30,		/* 256 pixel, so we require 32 bytes for this */
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 24,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
+  /* flipmode_x_offset = */ 0x000,
+  /* pixel_width = */ 240,
+  /* pixel_height = */ 128
+};
+
+
+static const uint8_t u8x8_d_ssd1322_240x128_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, 0x7f),			/* multiplex ratio 1/128 Duty (0x0F~0x7F) */  
+  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, 0x36, 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_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_ssd1322_240x128_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_240x128_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 
   NHD-2.7-12864WDW3-M 
@@ -454,7 +551,7 @@ static const u8x8_display_info_t u8x8_ssd1322_128x64_display_info =
   /* data_setup_time_ns = */ 10,
   /* data_setup_time_ns = */ 10,
   /* write_pulse_width_ns = */ 150,	/* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
   /* write_pulse_width_ns = */ 150,	/* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,		/* 128 pixel */
   /* tile_width = */ 16,		/* 128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 28,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* default_x_offset = */ 28,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
   /* flipmode_x_offset = */ 28,
   /* flipmode_x_offset = */ 28,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -476,6 +573,29 @@ static const uint8_t u8x8_d_ssd1322_128x64_init_seq[] = {
 
 
   U8X8_CA(0xa1, 0x00),			/* display start line */  
   U8X8_CA(0xa1, 0x00),			/* display start line */  
   U8X8_CA(0xab, 0x01),			/* Enable Internal VDD Regulator */  
   U8X8_CA(0xab, 0x01),			/* Enable Internal VDD Regulator */  
+/*
+	A[0]=0b, Horizontal address increment [reset]    ***
+	A[0]=1b, Vertical address increment
+	
+	A[1]=0b, Disable Column Address Re-map [reset]
+	A[1]=1b, Enable Column Address Re-map		***
+	
+	A[2]=0b, Disable Nibble Re-map [reset]
+	A[2]=1b, Enable Nibble Re-map			***
+	
+	A[4]=0b, Scan from COM0 to COM[N –1] [reset]	
+	A[4]=1b, Scan from COM[N-1] to COM0, where N is the	***
+	
+	Multiplex ratio
+	A[5]=0b, Disable COM Split Odd Even [reset]	***
+	A[5]=1b, Enable COM Split Odd Even
+	
+	B[4], Enable / disable Dual COM Line mode
+	0b, Disable Dual COM mode [reset]
+	1b, Enable Dual COM mode (MUX ≤ 63)
+	
+	0x16 = 00010110
+*/
   //U8X8_CAA(0xa0, 0x14, 0x11),	/* Set Re-Map / Dual COM Line Mode */  
   //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, 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_CAA(0xa0, 0x16, 0x011),	/* Set Re-Map / Dual COM Line Mode (NHD-2.7-12864WDW3-M datasheet) */  

+ 2 - 2
components/u8g2/u8x8_d_ssd1325.c

@@ -282,7 +282,7 @@ static const u8x8_display_info_t u8x8_nhd_ssd1325_128x64_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	/* SSD1325 */
   /* write_pulse_width_ns = */ 60,	/* SSD1325 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,		/* x_offset is used as y offset for the SSD1325 */
   /* 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 */
   /* flipmode_x_offset = */ 8,		/* x_offset is used as y offset for the SSD1325 */
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -394,7 +394,7 @@ static const u8x8_display_info_t u8x8_ssd0323_os128064_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	/* SSD1325 */
   /* write_pulse_width_ns = */ 60,	/* SSD1325 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,		/* x_offset is used as y offset for the SSD1325 */
   /* 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 */
   /* flipmode_x_offset = */ 0,		/* x_offset is used as y offset for the SSD1325 */
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 1 - 1
components/u8g2/u8x8_d_ssd1326.c

@@ -257,7 +257,7 @@ static const u8x8_display_info_t u8x8_ssd1326_256x32_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	/* ssd1326 */
   /* write_pulse_width_ns = */ 60,	/* ssd1326 */
   /* tile_width = */ 32,
   /* tile_width = */ 32,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,		/* x_offset is used as y offset for the ssd1326 */
   /* 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 */
   /* flipmode_x_offset = */ 0,		/* x_offset is used as y offset for the ssd1326 */
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,

+ 96 - 5
components/u8g2/u8x8_d_ssd1327.c

@@ -227,7 +227,7 @@ static const u8x8_display_info_t u8x8_ssd1327_winstar_96x64_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	
   /* write_pulse_width_ns = */ 60,	
   /* tile_width = */ 12,
   /* tile_width = */ 12,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 16,		/* changed to 16, issue 1050 */
   /* default_x_offset = */ 16,		/* changed to 16, issue 1050 */
   /* flipmode_x_offset = */ 16,		/* changed to 16, issue 1050 */
   /* flipmode_x_offset = */ 16,		/* changed to 16, issue 1050 */
   /* pixel_width = */ 96,
   /* pixel_width = */ 96,
@@ -355,7 +355,7 @@ static const u8x8_display_info_t u8x8_ssd1327_96x96_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	
   /* write_pulse_width_ns = */ 60,	
   /* tile_width = */ 12,
   /* tile_width = */ 12,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 16,
   /* default_x_offset = */ 16,
   /* flipmode_x_offset = */ 16,		
   /* flipmode_x_offset = */ 16,		
   /* pixel_width = */ 96,
   /* pixel_width = */ 96,
@@ -479,7 +479,7 @@ static const u8x8_display_info_t u8x8_ssd1327_ea_w128128_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	
   /* write_pulse_width_ns = */ 60,	
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,		
   /* flipmode_x_offset = */ 0,		
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -599,7 +599,7 @@ static const u8x8_display_info_t u8x8_ssd1327_128x128_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	
   /* write_pulse_width_ns = */ 60,	
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,		
   /* flipmode_x_offset = */ 0,		
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -719,6 +719,97 @@ uint8_t u8x8_d_ssd1327_midas_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
   return 0;
   return 0;
 }
 }
 
 
+/*=============================================*/
+/*
+
+  ZJY-M150 128x128 
+
+  https://aliexpress.com/item/1005003784174529.html
+  https://github.com/olikraus/u8g2/issues/1960
+
+  Mostly like the MIDAS version, but requires the GPIO enabled.
+
+*/
+
+static const uint8_t u8x8_d_ssd1327_zjy_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_CA(0x0b5, 0x003),		/* Enable GPIO, issue 1960 */
+  
+  
+  U8X8_C(0x0a4),				/* normal display mode */
+    
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+uint8_t u8x8_d_ssd1327_zjy_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_zjy_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;
+}
 
 
 /*=============================================*/
 /*=============================================*/
 /*  
 /*  
@@ -833,7 +924,7 @@ static const u8x8_display_info_t u8x8_ssd1327_128x96_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	
   /* write_pulse_width_ns = */ 60,	
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,		
   /* flipmode_x_offset = */ 0,		
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 2 - 2
components/u8g2/u8x8_d_ssd1329.c

@@ -278,7 +278,7 @@ static const u8x8_display_info_t u8x8_ssd1329_128x96_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	/* ssd1329 */
   /* write_pulse_width_ns = */ 60,	/* ssd1329 */
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 0,		/* x_offset is used as y offset for the ssd1329 */
   /* 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 */
   /* flipmode_x_offset = */ 0,		/* x_offset is used as y offset for the ssd1329 */
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -495,7 +495,7 @@ static const u8x8_display_info_t u8x8_ssd1329_96x96_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 60,	/* ssd1329 */
   /* write_pulse_width_ns = */ 60,	/* ssd1329 */
   /* tile_width = */ 12,
   /* tile_width = */ 12,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */  0,          /* x offset for flip mode 0 */
   /* default_x_offset = */  0,          /* x offset for flip mode 0 */
   /* flipmode_x_offset = */ 16,		/* x offset for flip mode 1 */ 
   /* flipmode_x_offset = */ 16,		/* x offset for flip mode 1 */ 
   /* pixel_width = */ 96,
   /* pixel_width = */ 96,

+ 538 - 0
components/u8g2/u8x8_d_ssd1362.c

@@ -0,0 +1,538 @@
+/*
+
+  u8x8_d_ssd1362.c
+  
+  https://github.com/olikraus/u8g2/issues/2051
+  
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2022, 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.  
+
+
+  SSD1362: 
+    256 x 64 (ssd1322: 480 x 128)
+    16 gray scale
+
+
+  Note: Currently the external IREF is activated.
+  Maybe we need a constructor with internal IREF
+  
+*/
+#include "u8x8.h"
+
+
+
+
+static const uint8_t u8x8_d_ssd1362_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0af),		                /* ssd1362: display on */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1362_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0ae),		                /* ssd1362: display off */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+
+
+/*
+  input:
+    one tile (8 Bytes)
+  output:
+    Tile for SSD1362 (32 Bytes)
+*/
+
+static uint8_t u8x8_ssd1362_to32_dest_buf[32];
+
+static uint8_t *u8x8_ssd1362_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_ssd1362_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_ssd1362_to32_dest_buf;
+}
+
+/* special case for the 206x36 display: send only half of the last tile */
+static uint8_t *u8x8_ssd1362_8to24(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 < 3; j++ )
+  {
+    dest = u8x8_ssd1362_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+=3;
+      a >>= 1;
+      b >>= 1;
+    }
+  }
+  
+  return u8x8_ssd1362_to32_dest_buf;
+}
+
+
+uint8_t u8x8_d_ssd1362_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_ssd1362_256x64_init_seq);
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_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 );	/* ssd1362 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;		// convert from tile pos to display column
+      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+3 );	/* end */
+          u8x8_cad_SendData(u8x8, 32, u8x8_ssd1362_8to32(u8x8, ptr));
+	  
+	  ptr += 8;
+	  x += 4;
+	  c--;
+	} while( c > 0 );
+	
+	arg_int--;
+        
+      } while( arg_int > 0 );
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+uint8_t u8x8_d_ssd1362_common_0_75(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_ssd1362_256x64_init_seq);
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_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 );	/* ssd1362 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;		// convert from tile pos to display column
+      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 */
+          if ( x < 123 )
+          {
+            u8x8_cad_SendArg(u8x8, x );	/* start */
+            u8x8_cad_SendArg(u8x8, x+3 );	/* end */
+            u8x8_cad_SendData(u8x8, 32, u8x8_ssd1362_8to32(u8x8, ptr));
+          }
+          else
+          {
+            u8x8_cad_SendArg(u8x8, x );	/* start */
+            u8x8_cad_SendArg(u8x8, x+2 );	/* end */
+            u8x8_cad_SendData(u8x8, 24, u8x8_ssd1362_8to24(u8x8, ptr));
+          }
+	  
+	  ptr += 8;
+	  x += 4;
+	  c--;
+	} while( c > 0 );
+	
+	arg_int--;
+        
+      } while( arg_int > 0 );
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+
+/*=========================================================*/
+
+static const uint8_t u8x8_d_ssd1362_256x64_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CA(0xa0, 0xc3), //Set Remap c3 = 11000011  
+  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1362_256x64_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CA(0xa0, 0xd0), 
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const u8x8_display_info_t u8x8_ssd1362_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, 	/* ssd1362: 2 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* ssd1362: 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* ssd1362: 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,	/* ssd1362: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 32,		/* 256 pixel, so we require 32 bytes for this */
+  /* tile_height = */ 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
+};
+
+
+/* https://github.com/olikraus/u8g2/issues/2051 */
+static const uint8_t u8x8_d_ssd1362_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(0x23, 0x00), //POR 0x00; Disable fade mode
+  U8X8_CA(0x81, 0x9f), //Set contrast
+  
+/*
+Re- map setting in Graphic Display Data RAM
+(GDDRAM)
+
+A[0] = 0b, Disable Column Address Re-map (RESET)
+A[0] = 1b, Enable Column Address Re-map			***
+
+A[1] = 0b, Disable Nibble Re-map (RESET)
+A[1] = 1b, Enable Nibble Re-map				***
+
+A[2] = 0b, Enable Horizontal Address Increment (RESET)   ***
+A[2] = 1b, Enable Vertical Address Increment
+
+A[4] = 0b, Disable COM Re-map (RESET)
+A[4] = 1b, Enable COM Re-map
+
+A[6] = 0b, Disable SEG Split Odd Even			***
+A[6] = 1b, Enable SEG Split Odd Even (RESET)
+
+A[7] = 0b, Disable SEG left/right remap (RESET)
+A[7] = 1b, Enable SEG left/right remap
+
+*/
+  U8X8_CA(0xa0, 0xc3), 
+  U8X8_CA(0xa1, 0), //Set Display Start Line
+  U8X8_CA(0xa2, 0), //Set Display Offset
+  U8X8_C(0xa4), //Normal Display
+  U8X8_CA(0xa8, 63), //Set Multiplex Ratio: (63 rows)
+  U8X8_CA(0xab, 1), //Set VDD regulator
+  U8X8_CA(0xad, 0x8e), //External /Internal IREF Selection, 9e: internal, 8e: external
+  U8X8_CA(0xb1, 0x22), //Set Phase Length, reset: 0x82
+  U8X8_CA(0xb3, 0xa0), //Display clock Divider
+  U8X8_CA(0xb6, 0x04), //Set Second precharge Period
+  U8X8_C(0xb9), //Set Linear LUT
+  U8X8_CA(0xbc, 0x1f), //Set pre-charge voltage level, 0..0x1f, 0x1f = 0.51*Vcc
+  U8X8_CA(0xbd, 1), //Pre-charge voltage capacitor Selection, 0: without, 1: with Vp capacitor
+  U8X8_CA(0xbe, 7), //Set cOM deselect voltage level, 7 = 0.86*Vcc
+  U8X8_DLY(1),					/* delay 1ms */
+
+  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+uint8_t u8x8_d_ssd1362_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_ssd1362_256x64_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_256x64_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_256x64_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_256x64_flip1_seq);
+	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+    
+    default:
+      return u8x8_d_ssd1362_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+
+/*=========================================================*/
+
+static const u8x8_display_info_t u8x8_ssd1362_206x36_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, 	/* ssd1362: 2 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* ssd1362: 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* ssd1362: 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,	/* ssd1362: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 26,		/* 26*8 = 208 */
+  /* tile_height = */ 5,                /* 5*8 = 40 */
+  /* default_x_offset = */ 0,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
+  /* flipmode_x_offset = */ 25, 
+  /* pixel_width = */ 206,
+  /* pixel_height = */ 36
+};
+
+
+/* https://github.com/olikraus/u8g2/issues/2051 */
+static const uint8_t u8x8_d_ssd1362_206x36_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(0x23, 0x00), //POR 0x00; Disable fade mode
+  U8X8_CA(0x81, 0x9f), //Set contrast
+  
+/*
+Re- map setting in Graphic Display Data RAM
+(GDDRAM)
+
+A[0] = 0b, Disable Column Address Re-map (RESET)
+A[0] = 1b, Enable Column Address Re-map			***
+
+A[1] = 0b, Disable Nibble Re-map (RESET)
+A[1] = 1b, Enable Nibble Re-map				***
+
+A[2] = 0b, Enable Horizontal Address Increment (RESET)   ***
+A[2] = 1b, Enable Vertical Address Increment
+
+A[4] = 0b, Disable COM Re-map (RESET)
+A[4] = 1b, Enable COM Re-map
+
+A[6] = 0b, Disable SEG Split Odd Even			***
+A[6] = 1b, Enable SEG Split Odd Even (RESET)
+
+A[7] = 0b, Disable SEG left/right remap (RESET)
+A[7] = 1b, Enable SEG left/right remap
+
+*/
+  U8X8_CA(0xa0, 0xc3), 
+  U8X8_CA(0xa1, 50), //Set Display Start Line
+  U8X8_CA(0xa2, 0), //Set Display Offset
+  U8X8_C(0xa4), //Normal Display
+  U8X8_CA(0xa8, 63), //Set Multiplex Ratio
+  U8X8_CA(0xab, 1), //Set VDD regulator
+  U8X8_CA(0xad, 0x8e), //External /Internal IREF Selection, 9e: internal, 8e: external
+  U8X8_CA(0xb1, 0x22), //Set Phase Length, reset: 0x82
+  U8X8_CA(0xb3, 0xa0), //Display clock Divider
+  U8X8_CA(0xb6, 0x04), //Set Second precharge Period
+  U8X8_C(0xb9), //Set Linear LUT
+  U8X8_CA(0xbc, 0x1f), //Set pre-charge voltage level, 0..0x1f, 0x1f = 0.51*Vcc
+  U8X8_CA(0xbd, 1), //Pre-charge voltage capacitor Selection, 0: without, 1: with Vp capacitor
+  U8X8_CA(0xbe, 7), //Set cOM deselect voltage level, 7 = 0.86*Vcc
+  U8X8_DLY(1),					/* delay 1ms */
+
+  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+uint8_t u8x8_d_ssd1362_206x36(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_ssd1362_206x36_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_206x36_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_256x64_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1362_256x64_flip1_seq);
+	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+    
+    default:
+      return u8x8_d_ssd1362_common_0_75(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}

+ 1 - 1
components/u8g2/u8x8_d_ssd1606_172x72.c

@@ -374,7 +374,7 @@ static const u8x8_display_info_t u8x8_ssd1606_172x72_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 22,		/* 22*8 = 176 */
   /* tile_width = */ 22,		/* 22*8 = 176 */
-  /* tile_hight = */ 9,		/* 9*8 = 72 */
+  /* tile_height = */ 9,		/* 9*8 = 72 */
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 172,
   /* pixel_width = */ 172,

+ 1 - 1
components/u8g2/u8x8_d_ssd1607_200x200.c

@@ -80,7 +80,7 @@ static const u8x8_display_info_t u8x8_ssd1607_200x200_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 150,	
   /* write_pulse_width_ns = */ 150,	
   /* tile_width = */ 25,		/* 25*8 = 200 */
   /* tile_width = */ 25,		/* 25*8 = 200 */
-  /* tile_hight = */ 25,		
+  /* tile_height = */ 25,		
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 200,
   /* pixel_width = */ 200,

+ 1 - 1
components/u8g2/u8x8_d_st7511.c

@@ -94,7 +94,7 @@ static const u8x8_display_info_t u8x8_st7511_320x240_display_info =
   /* data_setup_time_ns = */ 200,	/* */
   /* data_setup_time_ns = */ 200,	/* */
   /* write_pulse_width_ns = */ 250,	/* ST7511 Datasheet: 500ns */
   /* write_pulse_width_ns = */ 250,	/* ST7511 Datasheet: 500ns */
   /* tile_width = */ 40,		/* width of 17*8=136 pixel */
   /* tile_width = */ 40,		/* width of 17*8=136 pixel */
-  /* tile_hight = */ 30,
+  /* tile_height = */ 30,
   /* default_x_offset = */ 160,
   /* default_x_offset = */ 160,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 320,
   /* pixel_width = */ 320,

+ 54 - 46
components/u8g2/u8x8_d_st75160.c

@@ -31,7 +31,10 @@
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 
 
-  https://github.com/olikraus/u8g2/issues/1642
+  REQUESTED IN
+    https://github.com/olikraus/u8g2/issues/1642
+    
+  STATUS 13 Aug 2022: NOT TESTED, MAY NOT WORK..
 
 
 
 
   0x030	ext 00
   0x030	ext 00
@@ -84,29 +87,32 @@ static const uint8_t u8x8_d_st75256_256x128_powersave1_seq[] = {
   U8X8_END()             			/* end of sequence */
   U8X8_END()             			/* end of sequence */
 };
 };
 
 
-// static const uint8_t u8x8_d_st75256_jlx256128_flip0_seq[] = {
-//   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
-//   U8X8_C( 0x030 ),				/* select 00 commands */
-//   U8X8_CA( 0xbc, 0x00 ),			/* data scan dir */
-//   U8X8_A( 0xa6 ),				/* ??? */
-
-//   //U8X8_C( 0x030 ),				/* select 00 commands */
-//   U8X8_C( 0x00c ),				/* data format LSB top */
-//   U8X8_END_TRANSFER(),             	/* disable chip */
-//   U8X8_END()             			/* end of sequence */
-// };
-
-// static const uint8_t u8x8_d_st75256_jlx256128_flip1_seq[] = {
-//   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
-//   U8X8_C( 0x030 ),				/* select 00 commands */
-//   U8X8_CA( 0xbc, 0x03 ),			/* data scan dir */
-//   U8X8_A( 0xa6 ),				/* ??? */
-
-//   //U8X8_C( 0x030 ),				/* select 00 commands */
-//   U8X8_C( 0x008 ),				/* data format MSB top */
-//   U8X8_END_TRANSFER(),             	/* disable chip */
-//   U8X8_END()             			/* end of sequence */
-// };
+/* marked as unused to avoid compiler warning, issue 1802 */
+#ifdef NOT_USED
+static const uint8_t u8x8_d_st75256_jlx256128_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CA( 0xbc, 0x00 ),			/* data scan dir */
+  U8X8_A( 0xa6 ),				/* ??? */
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_C( 0x00c ),				/* data format LSB top */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st75256_jlx256128_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CA( 0xbc, 0x03 ),			/* data scan dir */
+  U8X8_A( 0xa6 ),				/* ??? */
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_C( 0x008 ),				/* data format MSB top */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+#endif
 
 
 static const uint8_t u8x8_d_st75256_jlx172104_flip0_seq[] = {
 static const uint8_t u8x8_d_st75256_jlx172104_flip0_seq[] = {
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
@@ -132,30 +138,32 @@ static const uint8_t u8x8_d_st75256_jlx172104_flip1_seq[] = {
   U8X8_END()             			/* end of sequence */
   U8X8_END()             			/* end of sequence */
 };
 };
 
 
-// static const uint8_t u8x8_d_st75256_jlx256160_flip0_seq[] = {
-//   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
-//   U8X8_C( 0x030 ),				/* select 00 commands */
-//   U8X8_CA( 0xbc, 0x00 ),			/* data scan dir */
-//   U8X8_A( 0xa6 ),				/* ??? */
-
-//   //U8X8_C( 0x030 ),				/* select 00 commands */
-//   U8X8_C( 0x00c ),				/* data format LSB top */
-//   U8X8_END_TRANSFER(),             	/* disable chip */
-//   U8X8_END()             			/* end of sequence */
-// };
+/* marked as unused to avoid compiler warning, issue 1802 */
+#ifdef NOT_USED
+static const uint8_t u8x8_d_st75256_jlx256160_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CA( 0xbc, 0x00 ),			/* data scan dir */
+  U8X8_A( 0xa6 ),				/* ??? */
 
 
-// static const uint8_t u8x8_d_st75256_jlx256160_flip1_seq[] = {
-//   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
-//   U8X8_C( 0x030 ),				/* select 00 commands */
-//   U8X8_CA( 0xbc, 0x03 ),			/* data scan dir */
-//   U8X8_A( 0xa6 ),				/* ??? */
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_C( 0x00c ),				/* data format LSB top */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
 
 
-//   //U8X8_C( 0x030 ),				/* select 00 commands */
-//   U8X8_C( 0x008 ),				/* data format MSB top */
-//   U8X8_END_TRANSFER(),             	/* disable chip */
-//   U8X8_END()             			/* end of sequence */
-// };
+static const uint8_t u8x8_d_st75256_jlx256160_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CA( 0xbc, 0x03 ),			/* data scan dir */
+  U8X8_A( 0xa6 ),				/* ??? */
 
 
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_C( 0x008 ),				/* data format MSB top */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+#endif
 
 
 
 
 /*=============================================*/
 /*=============================================*/
@@ -178,7 +186,7 @@ static const u8x8_display_info_t u8x8_st75160_jm16096_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 20,
   /* tile_width = */ 20,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 0,	/*  x offset in flipmode 0 */
   /* default_x_offset = */ 0,	/*  x offset in flipmode 0 */
   /* flipmode_x_offset = */ 0,		/* */
   /* flipmode_x_offset = */ 0,		/* */
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,

+ 221 - 8
components/u8g2/u8x8_d_st75256.c

@@ -251,7 +251,7 @@ static const u8x8_display_info_t u8x8_st75256_256x128_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 32,
   /* tile_width = */ 32,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,	/* must be 0, because this is checked also for normal mode */
   /* default_x_offset = */ 0,	/* must be 0, because this is checked also for normal mode */
   /* flipmode_x_offset = */ 5,		/* used as y offset */
   /* flipmode_x_offset = */ 5,		/* used as y offset */
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,
@@ -386,7 +386,7 @@ static const u8x8_display_info_t u8x8_st75256_wo256x128_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 32,
   /* tile_width = */ 32,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 5,	/* must be 0, because this is checked also for normal mode */
   /* default_x_offset = */ 5,	/* must be 0, because this is checked also for normal mode */
   /* flipmode_x_offset = */ 0,		/* used as y offset */
   /* flipmode_x_offset = */ 0,		/* used as y offset */
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,
@@ -520,7 +520,7 @@ static const u8x8_display_info_t u8x8_st75256_256x64_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 32,
   /* tile_width = */ 32,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,	/* must be 0, because this is checked also for normal mode */
   /* default_x_offset = */ 0,	/* must be 0, because this is checked also for normal mode */
   /* flipmode_x_offset = */ 13,		/* used as y offset */
   /* flipmode_x_offset = */ 13,		/* used as y offset */
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,
@@ -654,7 +654,7 @@ static const u8x8_display_info_t u8x8_st75256_172x104_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 22,			/* 22=176 */
   /* tile_width = */ 22,			/* 22=176 */
-  /* tile_hight = */ 13,
+  /* tile_height = */ 13,
   /* default_x_offset = */ 84,	/*  */
   /* default_x_offset = */ 84,	/*  */
   /* flipmode_x_offset = */ 0,		
   /* flipmode_x_offset = */ 0,		
   /* pixel_width = */ 172,
   /* pixel_width = */ 172,
@@ -845,7 +845,7 @@ static const u8x8_display_info_t u8x8_st75256_240x160_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 30,
   /* tile_width = */ 30,
-  /* tile_hight = */ 20,
+  /* tile_height = */ 20,
   /* default_x_offset = */ 16,	/*  x offset in flipmode 0 */
   /* default_x_offset = */ 16,	/*  x offset in flipmode 0 */
   /* flipmode_x_offset = */ 0,		/* */
   /* flipmode_x_offset = */ 0,		/* */
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -1040,7 +1040,7 @@ static const u8x8_display_info_t u8x8_st75256_256x160_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 32,
   /* tile_width = */ 32,
-  /* tile_hight = */ 20,
+  /* tile_height = */ 20,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 1,	/* x offset is used as y offset in flipmode */
   /* flipmode_x_offset = */ 1,	/* x offset is used as y offset in flipmode */
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,
@@ -1399,7 +1399,7 @@ static const u8x8_display_info_t u8x8_st75256_256x160_alt_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 32,
   /* tile_width = */ 32,
-  /* tile_hight = */ 20,
+  /* tile_height = */ 20,
   /* default_x_offset = */ 0,	/*  x offset in flipmode 0 */
   /* default_x_offset = */ 0,	/*  x offset in flipmode 0 */
   /* flipmode_x_offset = */ 0,		/* */
   /* flipmode_x_offset = */ 0,		/* */
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,
@@ -1591,7 +1591,7 @@ static const u8x8_display_info_t u8x8_st75256_192x96_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 24,	
   /* tile_width = */ 24,	
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 0,	/*  */
   /* default_x_offset = */ 0,	/*  */
   /* flipmode_x_offset = */ 64,
   /* flipmode_x_offset = */ 64,
   /* pixel_width = */ 192,
   /* pixel_width = */ 192,
@@ -1729,7 +1729,220 @@ uint8_t u8x8_d_st75256_jlx19296(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
                 u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave0_seq);
                 u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave0_seq);
               else
               else
                 u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave1_seq);
                 u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave1_seq);
+              return 1;
+	case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+	    if ( arg_int == 0 )
+	    {
+	      u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx256160_flip0_seq);
+	      u8x8->x_offset = u8x8->display_info->default_x_offset;
+	    }
+	    else
+	    {
+	      u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx256160_flip1_seq);
+	      u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+	    }
+	    return 1;
+	    /*
+	    if ( arg_int == 0 )
+	    {
+	      u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx172104_flip0_seq);
+	      u8x8->x_offset = u8x8->display_info->default_x_offset;
+	    }
+	    else
+	    {
+	      u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx172104_flip1_seq); 
+	      u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+	    }
+	    return 1;
+	    */
+		
+#ifdef U8X8_WITH_SET_CONTRAST
+        case U8X8_MSG_DISPLAY_SET_CONTRAST:
+
+              u8x8_cad_StartTransfer(u8x8);
+              
+              u8x8_cad_SendCmd(u8x8, 0x030 );
+              u8x8_cad_SendCmd(u8x8, 0x081 );  /* there are 9 bit for the volume control */
+              u8x8_cad_SendArg(u8x8, (arg_int & 0x1f)<<1 );	/* lower 6 bit */
+              u8x8_cad_SendArg(u8x8, (arg_int>>5));		/* upper 3 bit */
+              
+              u8x8_cad_EndTransfer(u8x8);
+              return 1;
+#endif
+  }
+  return 0;
+}
+
+
+
+/*=============================================*/
+/* 
+  JLX16080 LCD 
+
+  https://github.com/olikraus/u8g2/issues/2058
+
+  WARNING: NOT FULLY TESTED in issue 2058!
+*/
+
+static const u8x8_display_info_t u8x8_st75256_jlx16080_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 20,
+  /* pre_chip_disable_wait_ns = */ 20,
+  /* reset_pulse_width_ms = */ 5, 	
+  /* post_reset_wait_ms = */ 5, 		/**/
+  /* sda_setup_time_ns = */ 20,		/* */
+  /* sck_pulse_width_ns = */ 40,	/*  */
+  /* 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 = */ 15,
+  /* write_pulse_width_ns = */ 70,	
+  /* tile_width = */ 20,	
+  /* tile_height = */ 10,
+  /* default_x_offset = */ 0,	/*  */
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 160,
+  /* pixel_height = */ 80
+};
+
+static const uint8_t u8x8_d_st75256_jlx16080_init_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_DLY(20),
+
+  U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_C( 0x094 ),				/* sleep out */
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_C( 0x0ae ),				/* display off */
+
+  U8X8_C( 0x031 ),				/* select 01 commands */
+  U8X8_CA( 0x0d7, 0x09f ),		/* disable auto read */  
+
+  //U8X8_C( 0x031 ),				/* select 01 commands */
+  U8X8_C( 0x032 ),				/* analog circuit set */
+  U8X8_A( 0x000 ),				/* code example: OSC Frequency adjustment */
+  U8X8_A( 0x001 ),				/* Frequency on booster capacitors 1 = 6KHz? */
+  U8X8_A( 0x003 ),				/* Bias: 1: 1/13, 2: 1/12, 3: 1/11, 4:1/10, 5:1/9 */
+    
+  //U8X8_C( 0x031 ),				/* select 01 commands */
+  U8X8_C( 0x020 ),				/* gray levels */
+  U8X8_A( 0x01 ),
+  U8X8_A( 0x03 ),
+  U8X8_A( 0x05 ),
+  U8X8_A( 0x07 ),
+  U8X8_A( 0x09),
+  U8X8_A( 0x0b ),
+  U8X8_A( 0x0d ),
+  U8X8_A( 0x10 ),
+  U8X8_A( 0x11 ),
+  U8X8_A( 0x13 ),
+  U8X8_A( 0x15 ),
+  U8X8_A( 0x17 ),
+  U8X8_A( 0x19 ),
+  U8X8_A( 0x1b ),
+  U8X8_A( 0x1d ),
+  U8X8_A( 0x1f ),
+ 
+  
+  U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CAA(0x75, 0, 0x4f),		/* row range */
+  U8X8_CAA(0x15, 0, 255),		/* col range */
+  
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CA( 0xbc, 0x00 ),			/* data scan dir */
+  U8X8_A( 0xa6 ),				/* ??? */
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_C( 0x00c ),				/* data format LSB top */
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */ 
+  U8X8_C( 0xca ),				/* display control, 3 args follow  */
+  U8X8_A( 0x00 ),				/* 0x00: no clock division, 0x04: devide clock */
+  U8X8_A( 0x9f ),				/* 1/160 duty value from the DS example code */
+  U8X8_A( 0x20 ),				/* nline off */ 
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */ 
+  U8X8_CA( 0x0f0, 0x010 ),		/* monochrome mode  = 0x010*/
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CAA( 0x81, 0x2e, 0x03 ),	/* Volume control */
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CA( 0x020, 0x00b ),		/* Power control: Regulator, follower & booster on */
+  U8X8_DLY(100),
+
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};    
+
+
+uint8_t u8x8_d_st75256_jlx16080(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;
+              
+              u8x8_cad_SendCmd(u8x8, 0x030 );	/* select command set */
+              u8x8_cad_SendCmd(u8x8, 0x075 );	/* row */
+            
+            
+	      //if ( u8x8->x_offset == 0 )		/* 0 means flip mode 1, then adjust y value */
+		//u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));
+	      //else
+		u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));
+              
+              
+              u8x8_cad_SendArg(u8x8, 0x04f);
+              //u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));
+              u8x8_cad_SendCmd(u8x8, 0x015 );	/* col */
+              u8x8_cad_SendArg(u8x8, x+u8x8->x_offset);
+              u8x8_cad_SendArg(u8x8, 255);
+              u8x8_cad_SendCmd(u8x8, 0x05c );	
+            
+              
+              do
+              {
+                c = ((u8x8_tile_t *)arg_ptr)->cnt;
+                ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+                c *= 8;
 
 
+                if ( c + x > 192u )
+                {
+                        c = 192u;
+                        c -= x;
+                }
+                      
+                u8x8_cad_SendData(u8x8, c, ptr); 	
+                x += c;
+                arg_int--;
+              } while( arg_int > 0 );
+              
+              u8x8_cad_EndTransfer(u8x8);
+              return 1;
+        case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+            //u8x8_SetI2CAddress(u8x8, 0x078);		/* lowest I2C adr of the ST75256 */
+            u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st75256_jlx16080_display_info);
+            return 1;
+        case U8X8_MSG_DISPLAY_INIT:
+            u8x8_d_helper_display_init(u8x8);
+            u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx16080_init_seq);
+            return 1;
+        case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+              if ( arg_int == 0 )
+                u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave0_seq);
+              else
+                u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_256x128_powersave1_seq);
               return 1;
               return 1;
 	case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
 	case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
 	    if ( arg_int == 0 )
 	    if ( arg_int == 0 )

+ 3 - 4
components/u8g2/u8x8_d_st7528.c

@@ -243,6 +243,7 @@ static const uint8_t u8x8_d_st7528_nhd_c160100_init_seq[] = {
   U8X8_C(0x0a0),		                /* ADC */
   U8X8_C(0x0a0),		                /* ADC */
   U8X8_C(0x0c8),		                /* SHL */
   U8X8_C(0x0c8),		                /* SHL */
   U8X8_CA(0x044, 0x000),		/* initial Com0 */
   U8X8_CA(0x044, 0x000),		/* initial Com0 */
+  U8X8_CA(0x040, 0x000),		/* y shift, issue https://github.com/olikraus/u8g2/issues/1828 */
   U8X8_C(0x0ab),		                /* start oscillator */
   U8X8_C(0x0ab),		                /* start oscillator */
   U8X8_C(0x026),		                /* Select the internal resistance ratio of the regulator resistor */
   U8X8_C(0x026),		                /* Select the internal resistance ratio of the regulator resistor */
   U8X8_CA(0x081, 0x015),		/* volumn */
   U8X8_CA(0x081, 0x015),		/* volumn */
@@ -262,8 +263,6 @@ static const uint8_t u8x8_d_st7528_nhd_c160100_init_seq[] = {
   U8X8_END()             			/* end of sequence */
   U8X8_END()             			/* end of sequence */
 };
 };
 
 
-
-
 static const u8x8_display_info_t u8x8_st7528_160x100_display_info =
 static const u8x8_display_info_t u8x8_st7528_160x100_display_info =
 {
 {
   /* chip_enable_level = */ 0,
   /* chip_enable_level = */ 0,
@@ -282,7 +281,7 @@ static const u8x8_display_info_t u8x8_st7528_160x100_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 80,	/* st7528 */
   /* write_pulse_width_ns = */ 80,	/* st7528 */
   /* tile_width = */ 20,
   /* tile_width = */ 20,
-  /* tile_hight = */ 13,
+  /* tile_height = */ 13,
   /* default_x_offset = */ 0,		/* x_offset is used as y offset for the ssd1326 */
   /* 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 */
   /* flipmode_x_offset = */ 0,		/* x_offset is used as y offset for the ssd1326 */
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,
@@ -434,7 +433,7 @@ static const u8x8_display_info_t u8x8_st7528_erc16064_display_info =
   /* data_setup_time_ns = */ 40,
   /* data_setup_time_ns = */ 40,
   /* write_pulse_width_ns = */ 80,	/* st7528 */
   /* write_pulse_width_ns = */ 80,	/* st7528 */
   /* tile_width = */ 20,
   /* tile_width = */ 20,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,		/* x_offset is used as y offset for the ssd1326 */
   /* 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 */
   /* flipmode_x_offset = */ 0,		/* x_offset is used as y offset for the ssd1326 */
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,

+ 1 - 1
components/u8g2/u8x8_d_st75320.c

@@ -242,7 +242,7 @@ static const u8x8_display_info_t u8x8_st75320_jlx320240_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 40,
   /* tile_width = */ 40,
-  /* tile_hight = */ 30,
+  /* tile_height = */ 30,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 320,
   /* pixel_width = */ 320,

+ 179 - 0
components/u8g2/u8x8_d_st7539.c

@@ -0,0 +1,179 @@
+/*
+
+  u8x8_d_st7539.c
+  
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2023, 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_st7539_192x64_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_st7539_192x64_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_st7539_192x64_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0c2),				/* bit 1: MX, bit 2: MY */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7539_192x64_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0c4),				/* bit 1: MX, bit 2: MY */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+static const u8x8_display_info_t u8x8_st7539_192x64_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 1,	/* st7539 datasheet, page 46 */
+  /* pre_chip_disable_wait_ns = */ 5,	/* st7539 datasheet, page 46 */
+  /* reset_pulse_width_ms = */ 1, 
+  /* post_reset_wait_ms = */ 6, 
+  /* sda_setup_time_ns = */ 12,		/* st7539 datasheet, page 44 */
+  /* sck_pulse_width_ns = */ 15,	/* st7539 datasheet, page 44 */
+  /* sck_clock_hz = */ 2000000UL,	/* */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 1,
+  /* data_setup_time_ns = */ 60,	/* st7539 datasheet, page 43 */
+  /* write_pulse_width_ns = */ 80,	/* st7539 datasheet, page 43 */
+  /* tile_width = */ 24,		
+  /* tile_height = */ 8,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 192,
+  /* pixel_height = */ 64
+};
+
+static const uint8_t u8x8_d_st7539_192x64_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_C(0x0e2),            			/* soft reset */
+  U8X8_C(0x0a0),            			/* 76Hz FPS*/
+  U8X8_C(0x0eb),            			/* LCD Bias: 0xe8: 6, 0xe9: 7, 0xea: 8, 0xeb: 9 */
+  U8X8_C(0x0c2),		                /* RAM mapping ctrl */
+  U8X8_CA(0x081, 145),		/* set contrast */
+  U8X8_C(0x02e),            			/* LCD Load + Internal Charge Pump (default: 0x2e) */	
+  U8X8_C(0x040),		                /* set display start line to 0 */
+  
+  U8X8_C(0x0a6),		                /* normal display */
+   
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+// https://github.com/olikraus/u8g2/issues/2146
+
+uint8_t u8x8_d_st7539_192x64(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_st7539_192x64_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7539_192x64_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7539_192x64_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7539_192x64_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7539_192x64_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7539_192x64_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 );	/* st7539 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;
+}
+

+ 13 - 13
components/u8g2/u8x8_d_st7565.c

@@ -105,7 +105,7 @@ static const u8x8_display_info_t u8x8_st7565_128x64_display_info =
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 4,
   /* flipmode_x_offset = */ 4,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -393,7 +393,7 @@ static const u8x8_display_info_t u8x8_st7565_64128n_display_info =
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 4,
   /* default_x_offset = */ 4,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -521,7 +521,7 @@ static const u8x8_display_info_t u8x8_st7565_128x32_display_info =
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 4,
   /* default_x_offset = */ 4,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -611,7 +611,7 @@ static const u8x8_display_info_t u8x8_st7565_nhd_c12864_display_info =
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 4,
   /* default_x_offset = */ 4,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -637,8 +637,8 @@ static const uint8_t u8x8_d_st7565_nhd_c12864_init_seq[] = {
   U8X8_C(0x0a2),		                /* LCD bias 1/9 */
   U8X8_C(0x0a2),		                /* LCD bias 1/9 */
   U8X8_C(0x02f),		                /* all power  control circuits on */
   U8X8_C(0x02f),		                /* all power  control circuits on */
   U8X8_CA(0x0f8, 0x000),		/* set booster ratio to 4x */
   U8X8_CA(0x0f8, 0x000),		/* set booster ratio to 4x */
-  U8X8_C(0x023),		                /* set V0 voltage resistor ratio to large*/
-  U8X8_CA(0x081, 180),			/* set contrast, contrast value NHD C12864, see issue 186, increased contrast to 180 (issue 219) */
+  U8X8_C(0x025),		                /* set V0 voltage resistor ratio to large,  issue 1678: changed from 0x23 to 0x25 */
+  U8X8_CA(0x081, 170),			/* set contrast, contrast value NHD C12864, see issue 186, increased contrast to 180 (issue 219), reduced to 170 (issue 1678) */
   
   
   U8X8_C(0x0ae),		                /* display off */
   U8X8_C(0x0ae),		                /* display off */
   U8X8_C(0x0a5),		                /* enter powersafe: all pixel on, issue 142 */
   U8X8_C(0x0a5),		                /* enter powersafe: all pixel on, issue 142 */
@@ -739,7 +739,7 @@ static const u8x8_display_info_t u8x8_st7565_lm6059_display_info =
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 1,	/* not sure... */
   /* default_x_offset = */ 1,	/* not sure... */
   /* flipmode_x_offset = */ 3,
   /* flipmode_x_offset = */ 3,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -819,12 +819,12 @@ uint8_t u8x8_d_st7565_ks0713(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
       case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
       case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
 	if ( arg_int == 0 )
 	if ( arg_int == 0 )
 	{
 	{
-	  u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip1_seq);
+	  u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_zflip1_seq);
 	  u8x8->x_offset = u8x8->display_info->default_x_offset;
 	  u8x8->x_offset = u8x8->display_info->default_x_offset;
 	}
 	}
 	else
 	else
 	{
 	{
-	  u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_flip0_seq);
+	  u8x8_cad_SendSequence(u8x8, u8x8_d_st7565_zflip0_seq);
 	  u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
 	  u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
 	}	
 	}	
 	break;
 	break;
@@ -886,7 +886,7 @@ static const u8x8_display_info_t u8x8_st7565_lx12864_display_info =
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 1,	/* not sure... */
   /* default_x_offset = */ 1,	/* not sure... */
   /* flipmode_x_offset = */ 3,
   /* flipmode_x_offset = */ 3,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -978,7 +978,7 @@ static const u8x8_display_info_t u8x8_st7565_erc12864_display_info =
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 4,
   /* flipmode_x_offset = */ 4,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -1210,7 +1210,7 @@ static const u8x8_display_info_t u8x8_st7565_dogm132_display_info =
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* data_setup_time_ns = */ 40,	/* st7565 datasheet, table 24, tds8 */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* write_pulse_width_ns = */ 80,	/* st7565 datasheet, table 24, tcclw */
   /* tile_width = */ 17,		/* width of 16*8=136 pixel */
   /* tile_width = */ 17,		/* width of 16*8=136 pixel */
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 132,
   /* pixel_width = */ 132,
@@ -1336,4 +1336,4 @@ uint8_t u8x8_d_st7565_jlx12864g109pc(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
     }
     }
   }
   }
   return 1;
   return 1;
-}
+}

+ 524 - 12
components/u8g2/u8x8_d_st7567.c

@@ -30,6 +30,9 @@
   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
+  
+  
+  ST7567: 65x132 controller
 
 
   
   
 */
 */
@@ -108,7 +111,7 @@ static const u8x8_display_info_t u8x8_st7567_132x64_display_info =
   /* data_setup_time_ns = */ 40,	/* */
   /* data_setup_time_ns = */ 40,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* tile_width = */ 17,		/* width of 17*8=136 pixel */
   /* tile_width = */ 17,		/* width of 17*8=136 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 132,
   /* pixel_width = */ 132,
@@ -232,9 +235,6 @@ uint8_t u8x8_d_st7567_pi_132x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
 /*=====================================================*/
 /*=====================================================*/
 
 
 
 
-
-
-
 static const u8x8_display_info_t u8x8_st7567_jlx12864_display_info =
 static const u8x8_display_info_t u8x8_st7567_jlx12864_display_info =
 {
 {
   /* chip_enable_level = */ 0,
   /* chip_enable_level = */ 0,
@@ -252,7 +252,7 @@ static const u8x8_display_info_t u8x8_st7567_jlx12864_display_info =
   /* data_setup_time_ns = */ 40,	/* */
   /* data_setup_time_ns = */ 40,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 4,
   /* default_x_offset = */ 4,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -371,6 +371,169 @@ uint8_t u8x8_d_st7567_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
 }
 }
 
 
 
 
+/*=====================================================*/
+
+/* Sinda Display (sindadisplay.com), SDGG 2232-07 */
+/* Issue 1759, 122x32 display, https://github.com/olikraus/u8g2/files/7894362/SDGG12232-07.pdf */
+/* copied from jlx12864 */
+
+static const uint8_t u8x8_d_st7567_122x32_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x040+32),		                /* set display start line to 32 */
+  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_122x32_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x040+0),		                /* set display start line to 0 */
+  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_st7567_122x32_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_height = */ 4,
+  /* default_x_offset = */ 4,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 122,
+  /* pixel_height = */ 32
+};
+
+static const uint8_t u8x8_st7567_122x32_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+32),		                /* set display start line to 32 */
+  
+  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. */
+  
+  
+  /* I think datasheet of the 122x32 display suggest to use 0x0a2 instead of 0xa3 here */
+  U8X8_C(0x0a2),		                /* LCD bias 1/6 @1/33 duty */
+  /* 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 */
+};
+
+/* 122x32 display, issue 1759 */
+uint8_t u8x8_d_st7567_122x32(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_122x32_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_st7567_122x32_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_122x32_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_122x32_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;
+}
+
+
 /*=====================================================*/
 /*=====================================================*/
 
 
 
 
@@ -392,7 +555,7 @@ static const u8x8_display_info_t u8x8_st7567_enh_dg128064_display_info =
   /* data_setup_time_ns = */ 40,	/* */
   /* data_setup_time_ns = */ 40,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 4,
   /* flipmode_x_offset = */ 4,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -416,7 +579,7 @@ static const u8x8_display_info_t u8x8_st7567_enh_dg128064i_display_info =
   /* data_setup_time_ns = */ 40,	/* */
   /* data_setup_time_ns = */ 40,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 4,
   /* default_x_offset = */ 4,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -593,7 +756,7 @@ static const u8x8_display_info_t u8x8_st7567_64x32_display_info =
   /* data_setup_time_ns = */ 40,	/* */
   /* data_setup_time_ns = */ 40,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* tile_width = */ 8,		
   /* tile_width = */ 8,		
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 32,
   /* default_x_offset = */ 32,
   /* flipmode_x_offset = */ 32,
   /* flipmode_x_offset = */ 32,
   /* pixel_width = */ 64,
   /* pixel_width = */ 64,
@@ -733,7 +896,7 @@ static const u8x8_display_info_t u8x8_st7567_hem6432_display_info =
   /* data_setup_time_ns = */ 40,	/* */
   /* data_setup_time_ns = */ 40,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* tile_width = */ 8,		
   /* tile_width = */ 8,		
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 36,		/* issue 1159 */
   /* default_x_offset = */ 36,		/* issue 1159 */
   /* flipmode_x_offset = */ 32,		/* issue 1159 */
   /* flipmode_x_offset = */ 32,		/* issue 1159 */
   /* pixel_width = */ 64,
   /* pixel_width = */ 64,
@@ -860,8 +1023,6 @@ uint8_t u8x8_d_st7567_hem6432(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
 
 
 
 
 
 
-
-
 static const u8x8_display_info_t u8x8_st7567_os12864_display_info =
 static const u8x8_display_info_t u8x8_st7567_os12864_display_info =
 {
 {
   /* chip_enable_level = */ 0,
   /* chip_enable_level = */ 0,
@@ -879,7 +1040,7 @@ static const u8x8_display_info_t u8x8_st7567_os12864_display_info =
   /* data_setup_time_ns = */ 40,	/* */
   /* data_setup_time_ns = */ 40,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* write_pulse_width_ns = */ 80,	/* */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 4,
   /* default_x_offset = */ 4,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -998,3 +1159,354 @@ uint8_t u8x8_d_st7567_os12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
 }
 }
 
 
 
 
+/*=====================================================*/
+/*
+
+  https://github.com/olikraus/u8g2/discussions/1868
+  https://github.com/olikraus/u8g2/issues/1869
+  https://www.buydisplay.com/cog-serial-spi-132x32-graphic-lcd-display-no-backlight-st7567a
+
+  ERC13232
+
+  copied from U8G2_ST7567_PI_132X64
+
+*/
+
+static const u8x8_display_info_t u8x8_st7567_132x32_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_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 132,
+  /* pixel_height = */ 32
+};
+
+static const uint8_t u8x8_d_st7567_erc13232_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 */
+};
+
+/* ERC13232 */
+uint8_t u8x8_d_st7567_erc13232(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_132x32_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7567_erc13232_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;
+}
+
+
+/*=====================================================*/
+
+/* LW12864 display, 128x32 (actually 142x36, but with border of weird behavior) */
+/* copied from jlx12864 */
+
+static const u8x8_display_info_t u8x8_st7567_lw12832_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,		/* rounded up to 17 tiles */
+  /* tile_height = */ 9,    /* also rounded */
+  /* default_x_offset = */ 4,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 32
+};
+
+static const uint8_t u8x8_st7567_lw12832_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 */
+};
+
+static void st7567_lw12832_clear_ddram(u8x8_t *u8x8)
+{
+  // A combination of
+  //     - void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf)
+  // and
+  //     - uint8_t u8x8_d_st7567_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+
+  uint8_t buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+  uint8_t h = u8x8->display_info->tile_height;
+
+  u8x8_tile_t tile;
+  tile.x_pos = 0;
+  tile.y_pos = 0;
+  tile.cnt = 1;
+  tile.tile_ptr = buf;
+
+  do
+  {
+    // Args
+    uint8_t arg_int = u8x8->display_info->tile_width;
+    void *arg_ptr = (void *)&tile;
+
+    // ---------------- START OF u8x8_d_st7567_jlx12864 case U8X8_MSG_DISPLAY_DRAW_TILE ----------------
+    uint8_t x, c;
+    uint8_t *ptr;
+
+    u8x8_cad_StartTransfer(u8x8);
+
+    x = ((u8x8_tile_t *)arg_ptr)->x_pos;
+    x *= 8;
+    /* x += u8x8->x_offset; */                                         // Note that this is removed intentionally
+    u8x8_cad_SendCmd(u8x8, 0x010 | (x >> 4));                          // Set Column Address (MSB)
+    u8x8_cad_SendCmd(u8x8, 0x000 | ((x & 15)));                        // Set Column Address (LSB)
+    u8x8_cad_SendCmd(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos)); // Set Page Address
+
+    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);
+    // ---------------- END OF u8x8_d_st7567_jlx12864 case U8X8_MSG_DISPLAY_DRAW_TILE  ----------------
+
+    tile.y_pos++;
+  } while (tile.y_pos < h);
+}
+
+/* LW12832 display */
+uint8_t u8x8_d_st7567_lw12832(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_lw12832_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_st7567_lw12832_init_seq);
+      st7567_lw12832_clear_ddram(u8x8);
+      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;
+}
+

+ 7 - 4
components/u8g2/u8x8_d_st7571.c

@@ -168,6 +168,7 @@ static uint8_t u8x8_d_st7571_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
 
 
 
 
 /* QT-2832TSWUG02/ZJY-2832TSWZG02 */
 /* QT-2832TSWUG02/ZJY-2832TSWZG02 */
+/* fixed the 0x40 and 0x48 commands, verified with FlipMode example: All ok */
 static const uint8_t u8x8_d_st7571_128x128_init_seq[] = {
 static const uint8_t u8x8_d_st7571_128x128_init_seq[] = {
     
     
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
@@ -181,14 +182,16 @@ static const uint8_t u8x8_d_st7571_128x128_init_seq[] = {
   U8X8_C(0xA0), 				// ADC select
   U8X8_C(0xA0), 				// ADC select
   U8X8_C(0xC8), 				// SHL select
   U8X8_C(0xC8), 				// SHL select
   U8X8_CA(0x44, 0x00), 		// COM0 register  
   U8X8_CA(0x44, 0x00), 		// COM0 register  
-  U8X8_CA(0x40, 0x7f), 		// initial display line  (0x7f... strange but ok... maybe specific for the JLX128128)
+  U8X8_CA(0x40, 0x0), 		// initial display line  (0x7f... strange but ok... maybe specific for the JLX128128)
                                                         // 2 sep 2021: maybe this also wrong because the 0x44 command is overwritten later.
                                                         // 2 sep 2021: maybe this also wrong because the 0x44 command is overwritten later.
+                                                        // 4 Mar 2022: Changed to 0
   
   
   U8X8_C(0xAB), 				// OSC ON  
   U8X8_C(0xAB), 				// OSC ON  
   U8X8_C(0x25), 				// Voltage regulator
   U8X8_C(0x25), 				// Voltage regulator
   U8X8_CA(0x81, 0x33), 		// Volume
   U8X8_CA(0x81, 0x33), 		// Volume
   U8X8_C(0x54), 				// LCD Bias: 0x056=1/11 (1/11 according to JLX128128 datasheet), 0x054=1/9
   U8X8_C(0x54), 				// LCD Bias: 0x056=1/11 (1/11 according to JLX128128 datasheet), 0x054=1/9
-  U8X8_CA(0x44, 0x7f), 		// Duty 1/128   // 2 Sep 2021: Should this be 00x48???
+  U8X8_CA(0x48, 0x80), 		// Duty 1/128   // 2 Sep 2021: Should this be 00x48???  
+                                                        // 4 Mar 2022, cmd changed to 0x48, arg changed to 0x80
   
   
   U8X8_C(0x2C), 				// Power Control, VC: ON, VR: OFF, VF: OFF
   U8X8_C(0x2C), 				// Power Control, VC: ON, VR: OFF, VF: OFF
   U8X8_DLY(200),
   U8X8_DLY(200),
@@ -232,7 +235,7 @@ static const u8x8_display_info_t u8x8_st7571_128x128_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -331,7 +334,7 @@ static const u8x8_display_info_t u8x8_st7571_128x96_display_info =
   /* data_setup_time_ns = */ 15,
   /* data_setup_time_ns = */ 15,
   /* write_pulse_width_ns = */ 70,	
   /* write_pulse_width_ns = */ 70,	
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 246 - 0
components/u8g2/u8x8_d_st7586s_jlx320160.c

@@ -0,0 +1,246 @@
+/*
+  u8x8_d_st7586s_jlx320160.c
+
+  Display: 320x160 pixel
+  ST7586s: 384 x 160 x 2
+
+  takeover from https://github.com/olikraus/u8g2/issues/1183
+  
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+  
+  Copyright (c) 2023, 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_jlx320160_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x036),  /* Scan Direction Setting */
+  U8X8_A(0x000),	/* COM159 -> COM0 SEG383 -> SEG0 */
+  U8X8_C(0x037),	/* Start line 0 */
+  U8X8_A(0x000),
+  U8X8_END_TRANSFER(),  /* disable chip */
+  U8X8_END()           	/* end of sequence */
+};
+
+/* Flip Mode is not supported, use u8g2 rotation instead */
+
+static const uint8_t u8x8_d_st7586s_jlx320160_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_END_TRANSFER(),  /* disable chip */
+  U8X8_END()            /* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7586s_jlx320160_init_seq[] = {
+  U8X8_START_TRANSFER(),/* enable chip */
+  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,70,1),// Vop
+
+  U8X8_CA(0x0C3,0x002), // BIAS: 0 = 1/14, 2 = 1/12
+
+  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(0x000), // 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(0), // COL0 -> COL127
+  U8X8_A(0), // 
+  U8X8_A(0), //
+  U8X8_A(112-1), // 112*3=336 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_TRANSFER(),/* disable chip */
+  U8X8_END()  /* end of sequence */
+};
+
+static const u8x8_display_info_t u8x8_st7586s_jlx320160_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 = */ 42,
+  /* 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 = */ 320,
+  /* pixel_height = */ 160
+};
+
+/*  https://github.com/olikraus/u8g2/issues/2186 */
+uint8_t u8x8_d_st7586s_jlx320160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 
+{  
+  uint16_t c;
+  uint8_t *ptr;
+  uint8_t i, byte;
+  uint32_t input;
+  uint8_t output[8];
+//  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_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;  //
+
+    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_INIT:
+    u8x8_d_helper_display_init(u8x8);
+    u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx320160_init_seq);
+    break;
+  case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+    u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7586s_jlx320160_display_info);
+    break;
+  case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+  	if ( arg_int == 0 )
+    {
+       u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx320160_flip0_seq);
+       u8x8->x_offset = u8x8->display_info->default_x_offset;
+    }
+    else
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx320160_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;
+}
+

+ 256 - 0
components/u8g2/u8x8_d_st7586s_jlx384160.c

@@ -0,0 +1,256 @@
+/*
+  u8x8_d_st7586s_jlx384160.c
+  
+  copyied from u8x8_d_st7586s_s028hn118a.c
+  
+  Display: 384x160 pixel, https://github.com/olikraus/u8g2/issues/1932
+  ST7586s: 384 x 160 x 2
+  
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+  
+  Copyright (c) 2022, 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_jlx384160_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_jlx384160_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 0 */
+  U8X8_A(0x000),
+  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_jlx384160_init_seq[] = {
+  U8X8_START_TRANSFER(),/* enable chip */
+  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(0x09f), // 160-1
+
+  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(159), // 160 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_TRANSFER(),/* disable chip */
+  U8X8_END()  /* end of sequence */
+};
+
+static const u8x8_display_info_t u8x8_st7586s_jlx384160_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 = */ 20,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 384,
+  /* pixel_height = */ 160
+};
+
+/*******************************************************************************
+ * st7586s_jlx384160 driver. This is the display in the SMART Response XE. This requires 16 bit mode.
+ ******************************************************************************/
+uint8_t u8x8_d_st7586s_jlx384160(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_jlx384160_init_seq);
+    break;
+  case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+    u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7586s_jlx384160_display_info);
+    break;
+  case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+  	if ( arg_int == 0 )
+    {
+       u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx384160_flip0_seq);
+       u8x8->x_offset = u8x8->display_info->default_x_offset;
+    }
+    else
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_jlx384160_flip1_seq);
+      u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+    }	
+    break;
+  default:
+    return 0;
+  }
+  return 1;
+}

+ 1 - 1
components/u8g2/u8x8_d_st7588.c

@@ -166,7 +166,7 @@ static const u8x8_display_info_t u8x8_st7588_128x64_display_info =
   /* data_setup_time_ns = */ 80,
   /* data_setup_time_ns = */ 80,
   /* write_pulse_width_ns = */ 50,	
   /* write_pulse_width_ns = */ 50,	
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,	/* must be 0, because this is checked also for normal mode */
   /* default_x_offset = */ 0,	/* must be 0, because this is checked also for normal mode */
   /* flipmode_x_offset = */ 4,		
   /* flipmode_x_offset = */ 4,		
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 114 - 14
components/u8g2/u8x8_d_st7920.c

@@ -152,7 +152,11 @@ uint8_t u8x8_d_st7920_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
   return 1;
   return 1;
 }
 }
 
 
-static const u8x8_display_info_t u8x8_st7920_192x32_display_info =
+
+/*=== 144x32 === */
+/* https://github.com/olikraus/u8g2/issues/209 */
+
+static const u8x8_display_info_t u8x8_st7920_144x32_display_info =
 {
 {
   /* chip_enable_level = */ 1,
   /* chip_enable_level = */ 1,
   /* chip_disable_level = */ 0,
   /* chip_disable_level = */ 0,
@@ -169,15 +173,40 @@ static const u8x8_display_info_t u8x8_st7920_192x32_display_info =
   /* i2c_bus_clock_100kHz = */ 4,
   /* i2c_bus_clock_100kHz = */ 4,
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
-  /* tile_width = */ 24,
-  /* tile_hight = */ 4,
+  /* tile_width = */ 18,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
-  /* pixel_width = */ 192,
+  /* pixel_width = */ 144,
   /* pixel_height = */ 32
   /* pixel_height = */ 32
 };
 };
 
 
-static const u8x8_display_info_t u8x8_st7920_128x64_display_info =
+
+uint8_t u8x8_d_st7920_144x32(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_144x32_display_info);
+      break;
+    default:
+      return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+
+
+
+
+
+
+
+
+
+/*=== 160x32 === */
+/* https://github.com/olikraus/u8g2/issues/1873, POWERTIP PG-16032LRU-BWH-H-P2 */
+
+static const u8x8_display_info_t u8x8_st7920_160x32_display_info =
 {
 {
   /* chip_enable_level = */ 1,
   /* chip_enable_level = */ 1,
   /* chip_disable_level = */ 0,
   /* chip_disable_level = */ 0,
@@ -189,20 +218,62 @@ static const u8x8_display_info_t u8x8_st7920_128x64_display_info =
   /* sda_setup_time_ns = */ 20,		
   /* sda_setup_time_ns = */ 20,		
   /* sck_pulse_width_ns = */  140,	/* datasheet ST7920 */
   /* 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 */
   /* 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  */
+  /* 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,
   /* i2c_bus_clock_100kHz = */ 4,
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
-  /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_width = */ 20,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
-  /* pixel_width = */ 128,
-  /* pixel_height = */ 64
+  /* pixel_width = */ 160,
+  /* pixel_height = */ 32
+};
+
+
+uint8_t u8x8_d_st7920_160x32(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_160x32_display_info);
+      break;
+    default:
+      return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+
+
+/*=== 192x32 === */
+
+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_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 192,
+  /* pixel_height = */ 32
 };
 };
 
 
+
 uint8_t u8x8_d_st7920_192x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 uint8_t u8x8_d_st7920_192x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
 {
   switch(msg)
   switch(msg)
@@ -216,6 +287,34 @@ uint8_t u8x8_d_st7920_192x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
   return 1;
   return 1;
 }
 }
 
 
+/*=== 128x64 === */
+
+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_height = */ 8,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 64
+};
+
 uint8_t u8x8_d_st7920_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 uint8_t u8x8_d_st7920_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
 {
   switch(msg)
   switch(msg)
@@ -229,6 +328,7 @@ uint8_t u8x8_d_st7920_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
   return 1;
   return 1;
 }
 }
 
 
+/*=== 256x32 === */
 /* https://github.com/olikraus/u8g2/issues/1593 */
 /* https://github.com/olikraus/u8g2/issues/1593 */
 
 
 static const u8x8_display_info_t u8x8_st7920_256x32_display_info =
 static const u8x8_display_info_t u8x8_st7920_256x32_display_info =
@@ -250,7 +350,7 @@ static const u8x8_display_info_t u8x8_st7920_256x32_display_info =
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
   /* tile_width = */ 32,
   /* tile_width = */ 32,
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,
@@ -269,4 +369,4 @@ uint8_t u8x8_d_st7920_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
 	  return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
 	  return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
   }
   }
   return 1;
   return 1;
-}
+}

+ 1 - 2
components/u8g2/u8x8_d_stdio.c

@@ -32,7 +32,7 @@
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 
 
 */
 */
-#if 0
+
 #include "u8x8.h"
 #include "u8x8.h"
 
 
 #include <stdio.h>
 #include <stdio.h>
@@ -99,4 +99,3 @@ void u8x8_SetupStdio(u8x8_t *u8x8)
   u8x8->display_cb = u8x8_d_stdio;
   u8x8->display_cb = u8x8_d_stdio;
 }
 }
 
 
-#endif

+ 87 - 6
components/u8g2/u8x8_d_t6963.c

@@ -140,7 +140,7 @@ static const u8x8_display_info_t u8x8_t6963_240x128_display_info =
   /* data_setup_time_ns = */ 80,
   /* data_setup_time_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* tile_width = */ 30,
   /* tile_width = */ 30,
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -224,7 +224,7 @@ static const u8x8_display_info_t u8x8_t6963_240x64_display_info =
   /* data_setup_time_ns = */ 80,
   /* data_setup_time_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* tile_width = */ 30,
   /* tile_width = */ 30,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -311,7 +311,7 @@ static const u8x8_display_info_t u8x8_t6963_256x64_display_info =
   /* data_setup_time_ns = */ 80,
   /* data_setup_time_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* tile_width = */ 32,
   /* tile_width = */ 32,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,
@@ -394,7 +394,7 @@ static const u8x8_display_info_t u8x8_t6963_128x64_display_info =
   /* data_setup_time_ns = */ 80,
   /* data_setup_time_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* tile_width = */ 16,
   /* tile_width = */ 16,
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -476,7 +476,7 @@ static const u8x8_display_info_t u8x8_t6963_160x80_display_info =
   /* data_setup_time_ns = */ 80,
   /* data_setup_time_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* write_pulse_width_ns = */ 80,
   /* tile_width = */ 20,
   /* tile_width = */ 20,
-  /* tile_hight = */ 10,
+  /* tile_height = */ 10,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,
@@ -559,6 +559,87 @@ uint8_t u8x8_d_t6963_128x64_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
 }
 }
 
 
 
 
+/*=============================================*/
+
+static const u8x8_display_info_t u8x8_t6963_128x128_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_height = */ 16,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 128
+};
+
+/* 128x64 */
+static const uint8_t u8x8_d_t6963_128x128_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_128x128(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_128x128_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_128x128_init_seq);
+      break;
+    default:
+      return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
   
   
 
 
-  
+  

+ 2 - 2
components/u8g2/u8x8_d_uc1601.c

@@ -88,7 +88,7 @@ static const u8x8_display_info_t u8x8_uc1601_128x32_display_info =
   /* data_setup_time_ns = */ 60,	/* uc1601 datasheet, page 43 */
   /* data_setup_time_ns = */ 60,	/* uc1601 datasheet, page 43 */
   /* write_pulse_width_ns = */ 80,	/* uc1601 datasheet, page 43 */
   /* write_pulse_width_ns = */ 80,	/* uc1601 datasheet, page 43 */
   /* tile_width = */ 16,		
   /* tile_width = */ 16,		
-  /* tile_hight = */ 4,
+  /* tile_height = */ 4,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 4,
   /* flipmode_x_offset = */ 4,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,
@@ -228,7 +228,7 @@ static const u8x8_display_info_t u8x8_uc1601_128x64_display_info =
   /* data_setup_time_ns = */ 60,	/* uc1601 datasheet, page 43 */
   /* data_setup_time_ns = */ 60,	/* uc1601 datasheet, page 43 */
   /* write_pulse_width_ns = */ 80,	/* uc1601 datasheet, page 43 */
   /* write_pulse_width_ns = */ 80,	/* uc1601 datasheet, page 43 */
   /* tile_width = */ 16,		
   /* tile_width = */ 16,		
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 2,
   /* default_x_offset = */ 2,
   /* flipmode_x_offset = */ 4,  /* IS THIS CORRECT? */
   /* flipmode_x_offset = */ 4,  /* IS THIS CORRECT? */
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 1 - 1
components/u8g2/u8x8_d_uc1604.c

@@ -172,7 +172,7 @@ static const u8x8_display_info_t u8x8_uc1604_192x64_display_info =
   /* data_setup_time_ns = */ 30,	
   /* data_setup_time_ns = */ 30,	
   /* write_pulse_width_ns = */ 35,	
   /* write_pulse_width_ns = */ 35,	
   /* tile_width = */ 24,		/* width of 24*8=192 pixel */
   /* tile_width = */ 24,		/* width of 24*8=192 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,	/* reused as y page offset */
   /* default_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* pixel_width = */ 192,
   /* pixel_width = */ 192,

+ 4 - 4
components/u8g2/u8x8_d_uc1608.c

@@ -165,7 +165,7 @@ static const u8x8_display_info_t u8x8_uc1608_240x64_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,	/* reused as y page offset */
   /* default_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 4,	/* reused as y page offset */
   /* flipmode_x_offset = */ 4,	/* reused as y page offset */
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -246,7 +246,7 @@ static const u8x8_display_info_t u8x8_uc1608_240x128_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,	/* reused as y page offset */
   /* default_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -327,7 +327,7 @@ static const u8x8_display_info_t u8x8_uc1608_erc240120_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 15,
+  /* tile_height = */ 15,
   /* default_x_offset = */ 1,	/* reused as y page offset */
   /* default_x_offset = */ 1,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -411,7 +411,7 @@ static const u8x8_display_info_t u8x8_uc1608_dem240064_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* data_setup_time_ns = */ 30,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
   /* write_pulse_width_ns = */ 35,	/* uc1608 datasheet, page 39 */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 1,	/* reused as y page offset */
   /* default_x_offset = */ 1,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* flipmode_x_offset = */ 0,	/* reused as y page offset */
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,

+ 1 - 1
components/u8g2/u8x8_d_uc1609.c

@@ -131,7 +131,7 @@ static const u8x8_display_info_t u8x8_uc1609_19264_display_info =
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
   /* tile_width = */ 24,		
   /* tile_width = */ 24,		
-  /* tile_hight = */ 8,		
+  /* tile_height = */ 8,		
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 192,
   /* pixel_width = */ 192,

+ 1 - 1
components/u8g2/u8x8_d_uc1610.c

@@ -158,7 +158,7 @@ static const u8x8_display_info_t u8x8_uc1610_display_info =
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
   /* tile_width = */ 20,		
   /* tile_width = */ 20,		
-  /* tile_hight = */ 13,		/* height of 13*8=104 pixel */
+  /* tile_height = */ 13,		/* height of 13*8=104 pixel */
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,

+ 5 - 5
components/u8g2/u8x8_d_uc1611.c

@@ -162,7 +162,7 @@ static const u8x8_display_info_t u8x8_uc1611_240x64_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -280,7 +280,7 @@ static const u8x8_display_info_t u8x8_uc1611_240x128_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -373,7 +373,7 @@ static const u8x8_display_info_t u8x8_uc1611_ew50850_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
   /* tile_width = */ 30,		/* width of 30*8=240 pixel */
-  /* tile_hight = */ 20,		/* height: 160 pixel */
+  /* tile_height = */ 20,		/* height: 160 pixel */
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 240,
   /* pixel_width = */ 240,
@@ -530,7 +530,7 @@ static const u8x8_display_info_t u8x8_uc1611_cg160160_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
-  /* tile_hight = */ 20,
+  /* tile_height = */ 20,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,
@@ -680,7 +680,7 @@ static const u8x8_display_info_t u8x8_uc1611_256x128_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* data_setup_time_ns = */ 30,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* write_pulse_width_ns = */ 80,	/* uc1611 datasheet, page 60 */
   /* tile_width = */ 32,		/* width of 32*8=256 pixel */
   /* tile_width = */ 32,		/* width of 32*8=256 pixel */
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 256,
   /* pixel_width = */ 256,

+ 1 - 1
components/u8g2/u8x8_d_uc1617.c

@@ -294,7 +294,7 @@ static const u8x8_display_info_t u8x8_uc1617_128x128_display_info =
   /* data_setup_time_ns = */ 30,	/* uc1617 datasheet, page 52 */
   /* data_setup_time_ns = */ 30,	/* uc1617 datasheet, page 52 */
   /* write_pulse_width_ns = */ 65,	/* uc1617 datasheet, page 52 */
   /* write_pulse_width_ns = */ 65,	/* uc1617 datasheet, page 52 */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* flipmode_x_offset = */ 0,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 76 - 2
components/u8g2/u8x8_d_uc1638.c

@@ -175,7 +175,7 @@ static const u8x8_display_info_t u8x8_uc1638_160x128_display_info =
   /* data_setup_time_ns = */ 30,	/*  */
   /* data_setup_time_ns = */ 30,	/*  */
   /* write_pulse_width_ns = */ 35,	/*  */
   /* write_pulse_width_ns = */ 35,	/*  */
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
   /* tile_width = */ 20,		/* width of 20*8=160 pixel */
-  /* tile_hight = */ 16,
+  /* tile_height = */ 16,
   /* default_x_offset = */ 0,	/* lower nibble: x offset, upper nibble: y offset */
   /* default_x_offset = */ 0,	/* lower nibble: x offset, upper nibble: y offset */
   /* flipmode_x_offset = */ 0,	/* lower nibble: x offset, upper nibble: y offset */
   /* flipmode_x_offset = */ 0,	/* lower nibble: x offset, upper nibble: y offset */
   /* pixel_width = */ 160,
   /* pixel_width = */ 160,
@@ -252,7 +252,7 @@ static const u8x8_display_info_t u8x8_uc1638_192x96_display_info =
   /* data_setup_time_ns = */ 30,	/*  */
   /* data_setup_time_ns = */ 30,	/*  */
   /* write_pulse_width_ns = */ 35,	/*  */
   /* write_pulse_width_ns = */ 35,	/*  */
   /* tile_width = */ 24,		/* width of 24*8=192 pixel */
   /* tile_width = */ 24,		/* width of 24*8=192 pixel */
-  /* tile_hight = */ 12,
+  /* tile_height = */ 12,
   /* default_x_offset = */ 8*16+0,	/* lower nibble: x offset, upper nibble: y offset */
   /* default_x_offset = */ 8*16+0,	/* lower nibble: x offset, upper nibble: y offset */
   /* flipmode_x_offset = */ 0*16+6,	/* lower nibble: x offset, upper nibble: y offset */
   /* flipmode_x_offset = */ 0*16+6,	/* lower nibble: x offset, upper nibble: y offset */
   /* pixel_width = */ 192,
   /* pixel_width = */ 192,
@@ -304,3 +304,77 @@ uint8_t u8x8_d_uc1638_192x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
   }
   }
   return 1;
   return 1;
 }
 }
+
+/*================================================*/
+/* issue https://github.com/olikraus/u8g2/issues/2075 */
+
+static const u8x8_display_info_t u8x8_uc1638_240x128_display_info =
+{
+  /* chip_enable_level = */ 0,	/* low active CS for this display */
+  /* chip_disable_level = */ 1,
+  
+  /* 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 = */ 25,		/* */
+  /* sck_pulse_width_ns = */ 65,	/* */
+  /* sck_clock_hz = */ 2000000UL,	/* 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 = */ 30,		/* width of 30*8=240 pixel */
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 0*16+0,	/* lower nibble: x offset, upper nibble: y offset */
+  /* flipmode_x_offset = */ 4*16+0,	/* lower nibble: x offset, upper nibble: y offset */
+  /* pixel_width = */ 240,
+  /* pixel_height = */ 128
+};
+
+static const uint8_t u8x8_d_uc1638_240x128_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(0x0c2),            		/*	mirror y and mirror x */ 
+  U8X8_C(0x0a2),            		/*	line rate */
+  //U8X8_C(0x02d),            		/*	charge pump, issue 2075: not used */
+  U8X8_C(0x0eb),            		/*	 set bias, issue 2075: 0x0eb*/
+  U8X8_CA(0x081, 120),            	/*	 set contrast, issue 2075 */
+  //U8X8_C(0x0d6),            		/*	gray scale 2 */
+  U8X8_C(0x095),            		/*	 set 1 bit per pixel, pattern 0*/
+  //U8X8_C(0x086),            		/*	 COM scan, issue 2075: not used */
+  //U8X8_CA(0x0f1, 159),            	/*	 COM End, issue 2075: not used */
+  U8X8_C(0x089),            		/*	 set auto increment, low bits are AC2 AC1 AC0 */  /* WAS 89 */
+  //U8X8_C(0x086),            		/*	 scan function 0x86 or 0x87: no effect*/
+  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+uint8_t u8x8_d_uc1638_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_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_240x128_display_info);
+	break;
+      case U8X8_MSG_DISPLAY_INIT:
+	u8x8_d_helper_display_init(u8x8);
+          u8x8_cad_SendSequence(u8x8, u8x8_d_uc1638_240x128_init_seq);
+	break;
+      default:
+	return 0;		/* msg unknown */
+    }
+  }
+  return 1;
+}
+

+ 1 - 1
components/u8g2/u8x8_d_uc1701_dogs102.c

@@ -117,7 +117,7 @@ static const u8x8_display_info_t u8x8_uc1701_display_info =
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
   /* tile_width = */ 13,		/* width of 13*8=104 pixel */
   /* tile_width = */ 13,		/* width of 13*8=104 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 30,
   /* flipmode_x_offset = */ 30,
   /* pixel_width = */ 102,
   /* pixel_width = */ 102,

+ 1 - 1
components/u8g2/u8x8_d_uc1701_mini12864.c

@@ -117,7 +117,7 @@ static const u8x8_display_info_t u8x8_uc1701_display_info =
   /* data_setup_time_ns = */ 30,
   /* data_setup_time_ns = */ 30,
   /* write_pulse_width_ns = */ 40,
   /* write_pulse_width_ns = */ 40,
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
   /* tile_width = */ 16,		/* width of 16*8=128 pixel */
-  /* tile_hight = */ 8,
+  /* tile_height = */ 8,
   /* default_x_offset = */ 0,
   /* default_x_offset = */ 0,
   /* flipmode_x_offset = */ 4,
   /* flipmode_x_offset = */ 4,
   /* pixel_width = */ 128,
   /* pixel_width = */ 128,

+ 1 - 1
components/u8g2/u8x8_debounce.c

@@ -136,7 +136,7 @@ uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
 #define U8X8_DEBOUNCE_WAIT 2
 #define U8X8_DEBOUNCE_WAIT 2
 /* do debounce and return a GPIO msg which indicates the event */
 /* do debounce and return a GPIO msg which indicates the event */
 /* returns 0, if there is no event */
 /* returns 0, if there is no event */
-#if defined(__GNUC__) && !defined(__CYGWIN__)
+#if defined(__GNUC__) && !defined(_WIN32)
 # pragma weak  u8x8_GetMenuEvent
 # pragma weak  u8x8_GetMenuEvent
 #endif
 #endif
 uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)
 uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8)

+ 3 - 2
components/u8g2/u8x8_display.c

@@ -134,7 +134,8 @@ void u8x8_InitInterface(u8x8_t *u8x8)
 */
 */
 void u8x8_InitDisplay(u8x8_t *u8x8)
 void u8x8_InitDisplay(u8x8_t *u8x8)
 {
 {
-  u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL);  
+  u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL);       /* this will call u8x8_d_helper_display_init() and send the init seqence to the display */
+  /* u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, 0, NULL);  */ /* It would make sense to call flip mode 0 here after U8X8_MSG_DISPLAY_INIT */
 }
 }
 
 
 void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable)
 void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable)
@@ -199,4 +200,4 @@ void u8x8_ClearLine(u8x8_t *u8x8, uint8_t line)
     tile.tile_ptr = (uint8_t *)buf;		/* tile_ptr should be const, but isn't */
     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);
     u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile);
   }  
   }  
-}
+}

File diff suppressed because it is too large
+ 170 - 170
components/u8g2/u8x8_fonts.c


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