Jelajahi Sumber

update:更新u8g2源码

Dozingfiretruck 4 bulan lalu
induk
melakukan
c07d70d84d
43 mengubah file dengan 8606 tambahan dan 748 penghapusan
  1. 2 0
      components/u8g2/luat_u8g2.h
  2. 111 46
      components/u8g2/mui.c
  3. 12 7
      components/u8g2/mui.h
  4. 857 187
      components/u8g2/mui_u8g2.c
  5. 53 2
      components/u8g2/mui_u8g2.h
  6. 289 5
      components/u8g2/u8g2.h
  7. 107 0
      components/u8g2/u8g2_arc.c
  8. 59 2
      components/u8g2/u8g2_bitmap.c
  9. 264 33
      components/u8g2/u8g2_d_memory.c
  10. 766 106
      components/u8g2/u8g2_d_setup.c
  11. 676 146
      components/u8g2/u8g2_fonts.c
  12. 5 0
      components/u8g2/u8g2_selection_list.c
  13. 1 0
      components/u8g2/u8log.c
  14. 45 3
      components/u8g2/u8x8.h
  15. 2 2
      components/u8g2/u8x8_8x8.c
  16. 53 6
      components/u8g2/u8x8_cad.c
  17. 311 0
      components/u8g2/u8x8_d_ch1120.c
  18. 2 2
      components/u8g2/u8x8_d_ks0108.c
  19. 42 0
      components/u8g2/u8x8_d_ls013b7dh03.c
  20. 138 0
      components/u8g2/u8x8_d_pcf8812.c
  21. 219 0
      components/u8g2/u8x8_d_s1d15300.c
  22. 83 0
      components/u8g2/u8x8_d_sed1330.c
  23. 10 2
      components/u8g2/u8x8_d_sh1107.c
  24. 1 1
      components/u8g2/u8x8_d_sh1108.c
  25. 119 29
      components/u8g2/u8x8_d_ssd1309.c
  26. 354 0
      components/u8g2/u8x8_d_ssd1312.c
  27. 215 0
      components/u8g2/u8x8_d_ssd1315_128x64_noname.c
  28. 166 0
      components/u8g2/u8x8_d_ssd1320.c
  29. 219 0
      components/u8g2/u8x8_d_ssd1322.c
  30. 344 0
      components/u8g2/u8x8_d_ssd1363.c
  31. 501 0
      components/u8g2/u8x8_d_st7302.c
  32. 694 0
      components/u8g2/u8x8_d_st7305.c
  33. 428 0
      components/u8g2/u8x8_d_st75161.c
  34. 114 0
      components/u8g2/u8x8_d_st75256.c
  35. 304 156
      components/u8g2/u8x8_d_st7567.c
  36. 76 0
      components/u8g2/u8x8_d_st7571.c
  37. 243 0
      components/u8g2/u8x8_d_st7586s_md240128.c
  38. 44 10
      components/u8g2/u8x8_d_st7920.c
  39. 82 0
      components/u8g2/u8x8_d_t6963.c
  40. 93 0
      components/u8g2/u8x8_d_uc1604.c
  41. 457 0
      components/u8g2/u8x8_d_uc1628.c
  42. 3 3
      components/u8g2/u8x8_display.c
  43. 42 0
      components/u8g2/u8x8_u8toa.c

+ 2 - 0
components/u8g2/luat_u8g2.h

@@ -21,6 +21,8 @@ typedef struct luat_u8g2_conf
     void* userdata;
 } luat_u8g2_conf_t;
 
+uint8_t u8x8_d_custom_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+
 int luat_u8g2_setup(luat_u8g2_conf_t *conf);
 
 int luat_u8g2_close(luat_u8g2_conf_t *conf);

+ 111 - 46
components/u8g2/mui.c

@@ -298,9 +298,10 @@ void mui_Init(mui_t *ui, void *graphics_data, fds_t *fds, muif_t *muif_tlist, si
   ui->muif_tlist = muif_tlist;
   ui->muif_tcnt = muif_tcnt;
   ui->graphics_data = graphics_data;
+  ui->last_form_stack_pos = -1;
 }
 
-int mui_find_uif(mui_t *ui, uint8_t id0, uint8_t id1)
+static int mui_find_uif(mui_t *ui, uint8_t id0, uint8_t id1)
 {
   size_t i;
   for( i = 0; i < ui->muif_tcnt; i++ )
@@ -460,7 +461,7 @@ static void mui_loop_over_form(mui_t *ui, uint8_t (*task)(mui_t *ui))
 /*
   n is the form number
 */
-fds_t *mui_find_form(mui_t *ui, uint8_t n)
+static fds_t *mui_find_form(mui_t *ui, uint8_t n)
 {
   fds_t *fds = ui->root_fds;
   uint8_t cmd;
@@ -487,20 +488,20 @@ fds_t *mui_find_form(mui_t *ui, uint8_t n)
 /* === task procedures (arguments for mui_loop_over_form) === */
 /* ui->fds contains the current field */
 
-uint8_t mui_task_draw(mui_t *ui)
+static 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)
+static 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)
+static 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 */
@@ -516,7 +517,7 @@ static uint8_t mui_uif_is_cursor_selectable(mui_t *ui)
   return 0;
 }
 
-uint8_t mui_task_find_prev_cursor_uif(mui_t *ui)
+static 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) )
@@ -531,7 +532,7 @@ uint8_t mui_task_find_prev_cursor_uif(mui_t *ui)
   return 0;     /* continue with the loop */
 }
 
-uint8_t mui_task_find_first_cursor_uif(mui_t *ui)
+static 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) )
@@ -545,7 +546,7 @@ uint8_t mui_task_find_first_cursor_uif(mui_t *ui)
   return 0;     /* continue with the loop */
 }
 
-uint8_t mui_task_find_last_cursor_uif(mui_t *ui)
+static 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) )
@@ -556,7 +557,7 @@ uint8_t mui_task_find_last_cursor_uif(mui_t *ui)
   return 0;     /* continue with the loop */
 }
 
-uint8_t mui_task_find_next_cursor_uif(mui_t *ui)
+static 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) )
@@ -575,7 +576,7 @@ uint8_t mui_task_find_next_cursor_uif(mui_t *ui)
   return 0;     /* continue with the loop */
 }
 
-uint8_t mui_task_get_current_cursor_focus_position(mui_t *ui)
+static 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) )
@@ -587,7 +588,8 @@ uint8_t mui_task_get_current_cursor_focus_position(mui_t *ui)
   return 0;     /* continue with the loop */
 }
 
-uint8_t mui_task_read_nth_selectable_field(mui_t *ui)
+#ifdef OBSOLETE
+static 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) )
@@ -598,8 +600,9 @@ uint8_t mui_task_read_nth_selectable_field(mui_t *ui)
   }
   return 0;     /* continue with the loop */
 }
+#endif
 
-uint8_t mui_task_find_execute_on_select_field(mui_t *ui)
+static uint8_t mui_task_find_execute_on_select_field(mui_t *ui)
 {
   if ( muif_get_cflags(ui->uif) & MUIF_CFLAG_IS_EXECUTE_ON_SELECT )
   {
@@ -651,7 +654,7 @@ void mui_Draw(mui_t *ui)
   mui_loop_over_form(ui, mui_task_draw);
 }
 
-void mui_next_field(mui_t *ui)
+static void mui_next_field(mui_t *ui)
 {
   mui_loop_over_form(ui, mui_task_find_next_cursor_uif);
   // ui->cursor_focus_position++;
@@ -677,36 +680,46 @@ void mui_next_field(mui_t *ui)
 */
 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;
+  if ( fds != NULL )
+  {
+    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;
+  }
+  ui->text[0] = '\0';
+  return 0;
 }
 
 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;
+  if ( fds != NULL )
+  {
+    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;
+  }
+  ui->text[0] = '\0';
+  return 0;
 }
 
 
@@ -793,39 +806,91 @@ uint8_t mui_GotoForm(mui_t *ui, uint8_t form_id, uint8_t initial_cursor_position
   return 1;
 }
 
-void mui_SaveForm(mui_t *ui)
+/* 
+  Save current form+cursor position. Used together with mui_RestoreForm 
+*/
+void mui_SaveFormWithCursorPosition(mui_t *ui, uint8_t cursor_pos)
 {
   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 ( ui->last_form_stack_pos < MUI_MENU_LAST_FORM_STACK_SIZE-1 )
+    ui->last_form_stack_pos++;
+  else  // discard the oldes entry
+  {
+    uint8_t i;
+    for( i = 0; i < ui->last_form_stack_pos; i++ )
+    {
+      ui->last_form_id[i] = ui->last_form_id[i+1];
+      ui->last_form_cursor_focus_position[i] = ui->last_form_cursor_focus_position[i+1];
+    }
+  }
+  
+  ui->last_form_fds = ui->cursor_focus_fds;             // 25 Aug 2024: I think this is not required, u8g2 data function will store the value manually in last_form_fds
+  ui->last_form_id[ui->last_form_stack_pos] = mui_get_fds_char(ui->current_form_fds+1);
+  ui->last_form_cursor_focus_position[ui->last_form_stack_pos] = cursor_pos;
+}
+
+/* 
+  Save current form+cursor position. Simplified version, which will not work with pseudo scrolling forms
+*/
+void mui_SaveForm(mui_t *ui)
+{
+  mui_SaveFormWithCursorPosition(ui, mui_GetCurrentCursorFocusPosition(ui));
 }
 
+
 /*
+  Restore previous saved form and cursor position.
   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.
+  returns 0 if there is no form to restore
 */
-void mui_RestoreForm(mui_t *ui)
+uint8_t mui_RestoreForm(mui_t *ui)
 {
-  mui_GotoForm(ui, ui->last_form_id, ui->last_form_cursor_focus_position);
+  MUI_DEBUG("mui_RestoreForm last_form_stack_pos=%d\n", ui->last_form_stack_pos);
+  if ( ui->last_form_stack_pos >= 0 )
+  {
+    uint8_t form_id = ui->last_form_id[ui->last_form_stack_pos];
+    uint8_t focus = ui->last_form_cursor_focus_position[ui->last_form_stack_pos];
+    ui->last_form_stack_pos--;
+    return mui_GotoForm(ui, form_id, focus);
+    //ui->last_form_fds = NULL;
+  }
+  return 0;
 }
 
 /*
   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);
+  uint8_t i;
   MUI_DEBUG("mui_SaveCursorPosition form_id=%d cursor_position=%d\n", form_id, cursor_position);
   
+  for( i = 0; i < MUI_MENU_CACHE_CNT; i++ )
+  {
+    if ( form_id == ui->menu_form_id[i] )
+    {
+      ui->menu_form_last_added = i;
+      break;
+    }
+  }
+  if ( i >= MUI_MENU_CACHE_CNT )
+  {
+      ui->menu_form_last_added++ ;
+      if ( ui->menu_form_last_added >= MUI_MENU_CACHE_CNT )
+        ui->menu_form_last_added = 0;
+  }
+    
+  /*
   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);

+ 12 - 7
components/u8g2/mui.h

@@ -223,7 +223,9 @@ struct muif_struct
 #define MUI_MAX_TEXT_LEN 41
 #endif
 
-#define MUI_MENU_CACHE_CNT 2
+#define MUI_MENU_CACHE_CNT 4
+
+#define MUI_MENU_LAST_FORM_STACK_SIZE 4
 
 struct mui_struct
 {
@@ -259,7 +261,7 @@ struct mui_struct
   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
+  uint8_t arg;          // extra argument of the field. For example the G: form is put here, assigned by MUI_XYA or MUI_XYAT 
   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()
@@ -270,14 +272,16 @@ struct mui_struct
   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
+  uint8_t last_form_id[MUI_MENU_LAST_FORM_STACK_SIZE];
+  uint8_t last_form_cursor_focus_position[MUI_MENU_LAST_FORM_STACK_SIZE];
+  fds_t *last_form_fds;           // not used by mui_RestoreForm, but can be used by field functions, warning: this is the FDS of the field, from where the jump started to the child (cursor_focus_fds)
+  int8_t last_form_stack_pos;
   
   /* menu cursor position backup */
+  /* idea is, to restore the cursor position if we jump to that form */
+  uint8_t menu_form_last_added;
   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)
@@ -583,8 +587,9 @@ 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_SaveFormWithCursorPosition(mui_t *ui, uint8_t cursor_pos); /* Save current form with manully provied cursor position, Used together with mui_RestoreForm */
 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 */
+uint8_t 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);
 

File diff ditekan karena terlalu besar
+ 857 - 187
components/u8g2/mui_u8g2.c


+ 53 - 2
components/u8g2/mui_u8g2.h

@@ -65,6 +65,7 @@
 #ifndef MUI_U8G2_H
 #define MUI_U8G2_H
 
+#include "u8g2.h"
 #include "mui.h"
 
 /*==========================================*/
@@ -122,6 +123,26 @@ typedef const struct mui_u8g2_u8_min_max_struct mui_u8g2_u8_min_max_t;
 #  define mui_u8g2_u8mm_get_valptr(u8mm) ((u8mm)->value)
 #endif
 
+struct mui_u8g2_s8_min_max_struct
+{
+  int8_t *value;
+  int8_t min;
+  int8_t max;
+} MUI_PROGMEM;
+
+typedef const struct mui_u8g2_s8_min_max_struct mui_u8g2_s8_min_max_t;
+
+#if defined(__GNUC__) && defined(__AVR__)
+#  define mui_u8g2_s8mm_get_min(u8mm) ((int8_t)mui_pgm_read(&((u8mm)->min)))
+#  define mui_u8g2_s8mm_get_max(u8mm) ((int8_t)mui_pgm_read(&((u8mm)->max)))
+#  define mui_u8g2_s8mm_get_valptr(u8mm) ((int8_t *)mui_pgm_wread(&((u8mm)->value)))
+#else
+#  define mui_u8g2_s8mm_get_min(u8mm) ((u8mm)->min)
+#  define mui_u8g2_s8mm_get_max(u8mm) ((u8mm)->max)
+#  define mui_u8g2_s8mm_get_valptr(u8mm) ((u8mm)->value)
+#endif
+
+
 
 struct mui_u8g2_u8_min_max_step_struct
 {
@@ -164,6 +185,8 @@ typedef const struct mui_u8g2_u8_min_max_step_struct mui_u8g2_u8_min_max_step_t;
 
 u8g2_uint_t mui_get_x(mui_t *ui);
 u8g2_uint_t mui_get_y(mui_t *ui);
+u8g2_uint_t mui_get_arg(mui_t *ui);
+char *mui_get_text(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);
@@ -180,15 +203,27 @@ void mui_u8g2_draw_button_if(mui_t *ui, u8g2_uint_t width, u8g2_uint_t padding_h
 
 /* ready to use field functions */
 
+uint8_t mui_hline(mui_t *ui, uint8_t msg);
+
 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_back_wm_fi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_btn_back_wm_if(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_btn_back_w2_fi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_btn_back_w2_if(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_btn_back_w1_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_btn_back_w1_fi(mui_t *ui, uint8_t msg);
+
+
+
+
 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 */
@@ -247,10 +282,26 @@ uint8_t mui_u8g2_set_font_style_function(mui_t *ui, uint8_t msg);
 
 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 */
 
+/* hex format */
+uint8_t mui_u8g2_x8_min_max_wm_mse_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_x8_min_max_wm_mud_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_x8_min_max_wm_mse_pf(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_x8_min_max_wm_mud_pf(mui_t *ui, uint8_t msg);
+
+#define MUIF_U8G2_S8_MIN_MAX(id, valptr, min, max, muif) \
+  MUIF(id, MUIF_CFLAG_IS_CURSOR_SELECTABLE,  \
+  (void *)((mui_u8g2_s8_min_max_t [] ) {{ (valptr) MUI_U8G2_COMMA (min) MUI_U8G2_COMMA (max)}}), \
+  (muif))
+
+uint8_t mui_u8g2_s8_min_max_wm_mse_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_s8_min_max_wm_mud_pi(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_s8_min_max_wm_mse_pf(mui_t *ui, uint8_t msg);
+uint8_t mui_u8g2_s8_min_max_wm_mud_pf(mui_t *ui, uint8_t msg);
+
+
 /*===== 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 */

+ 289 - 5
components/u8g2/u8g2.h

@@ -59,7 +59,9 @@
 #define U8G2_H
 
 #include "u8x8.h"
+#if (defined __LUATOS__) || defined (__USER_CODE__)
 #include "stdio.h"
+#endif
 /*
   The following macro enables 16 Bit mode. 
   Without defining this macro all calculations are done with 8 Bit (1 Byte) variables.
@@ -521,6 +523,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_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_12_2_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_15_4_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_15_4_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_15_4_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);
@@ -551,6 +556,9 @@ uint8_t *u8g2_m_50_30_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_18_21_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_18_21_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_18_21_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_9_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_9_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_20_9_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_11_6_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_11_6_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_11_6_f(uint8_t *page_cnt);
@@ -569,6 +577,9 @@ uint8_t *u8g2_m_30_15_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_30_16_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_30_16_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_30_16_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_16_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_16_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_32_16_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_16_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_16_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_20_16_f(uint8_t *page_cnt);
@@ -581,9 +592,6 @@ uint8_t *u8g2_m_20_13_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_30_20_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_30_20_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_30_20_f(uint8_t *page_cnt);
-uint8_t *u8g2_m_32_16_1(uint8_t *page_cnt);
-uint8_t *u8g2_m_32_16_2(uint8_t *page_cnt);
-uint8_t *u8g2_m_32_16_f(uint8_t *page_cnt);
 uint8_t *u8g2_m_40_30_1(uint8_t *page_cnt);
 uint8_t *u8g2_m_40_30_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_40_30_f(uint8_t *page_cnt);
@@ -599,6 +607,15 @@ 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_16_32_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_32_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_32_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_26_25_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_26_25_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_26_25_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_21_48_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_21_48_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_21_48_f(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_f(uint8_t *page_cnt);
@@ -623,6 +640,9 @@ uint8_t *u8g2_m_20_10_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_16_9_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_9_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_16_9_f(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_f(uint8_t *page_cnt);
@@ -650,6 +670,9 @@ 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_2(uint8_t *page_cnt);
 uint8_t *u8g2_m_1_1_f(uint8_t *page_cnt);
+uint8_t *u8g2_m_13_4_1(uint8_t *page_cnt);
+uint8_t *u8g2_m_13_4_2(uint8_t *page_cnt);
+uint8_t *u8g2_m_13_4_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);
@@ -822,6 +845,12 @@ void u8g2_Setup_sh1108_128x160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_m
 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_ch1120_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_ch1120_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_ch1120_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_ch1120_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_ch1120_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_ch1120_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_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);
@@ -900,6 +929,30 @@ void u8g2_Setup_ssd1309_128x64_noname0_f(u8g2_t *u8g2, const u8g2_cb_t *rotation
 void u8g2_Setup_ssd1309_i2c_128x64_noname0_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1309_i2c_128x64_noname0_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ssd1309_i2c_128x64_noname0_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1309_128x128_noname0_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1309_128x128_noname0_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1309_128x128_noname0_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1309_i2c_128x128_noname0_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1309_i2c_128x128_noname0_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1309_i2c_128x128_noname0_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_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_ssd1312_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_ssd1312_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_ssd1312_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_ssd1312_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_ssd1312_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_ssd1312_120x32_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_120x28_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_120x32_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_120x28_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_120x32_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_120x28_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_120x32_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_120x28_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_120x32_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_120x28_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_120x32_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_120x28_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_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_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_128x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -974,12 +1027,15 @@ void u8g2_Setup_ssd1327_zjy_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u
 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_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_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_i2c_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_i2c_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_i2c_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_i2c_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_i2c_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_i2c_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_i2c_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_i2c_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_i2c_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_visionox_128x96_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_visionox_128x96_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1029,6 +1085,15 @@ void u8g2_Setup_st7920_144x32_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_ms
 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_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_st7920_p_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_st7920_p_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_st7920_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_st7920_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_st7920_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_st7920_s_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_st7920_s_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_st7920_s_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_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);
@@ -1068,6 +1133,9 @@ void u8g2_Setup_ls027b7dh01_m0_400x240_f(u8g2_t *u8g2, const u8g2_cb_t *rotation
 void u8g2_Setup_ls013b7dh05_144x168_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ls013b7dh05_144x168_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_ls013b7dh05_144x168_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ls011b7dh03_160x68_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ls011b7dh03_160x68_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ls011b7dh03_160x68_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1701_ea_dogs102_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1701_ea_dogs102_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1701_ea_dogs102_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1080,6 +1148,9 @@ void u8g2_Setup_pcd8544_84x48_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_ms
 void u8g2_Setup_pcf8812_96x65_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_pcf8812_96x65_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_pcf8812_96x65_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_pcf8812_101x64_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_pcf8812_101x64_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_pcf8812_101x64_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_hx1230_96x68_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_hx1230_96x68_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_hx1230_96x68_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1089,6 +1160,12 @@ void u8g2_Setup_uc1604_jlx19264_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 void u8g2_Setup_uc1604_i2c_jlx19264_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1604_i2c_jlx19264_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1604_i2c_jlx19264_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_uc1604_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_uc1604_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_uc1604_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_uc1604_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_uc1604_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_uc1604_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_uc1608_erc24064_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1608_dem240064_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1608_erc24064_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1119,6 +1196,24 @@ void u8g2_Setup_uc1609_slg19264_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 void u8g2_Setup_uc1609_i2c_slg19264_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1609_i2c_slg19264_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_uc1609_i2c_slg19264_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_uc1628_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_uc1628_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_uc1628_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_uc1628_i2c_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_uc1628_i2c_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_uc1628_i2c_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_uc1628_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_uc1628_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_uc1628_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_uc1628_i2c_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_uc1628_i2c_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_uc1628_i2c_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_uc1628_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_uc1628_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_uc1628_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_uc1628_i2c_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_uc1628_i2c_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_uc1628_i2c_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_uc1638_160x128_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_160x128_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_160x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1284,6 +1379,15 @@ void u8g2_Setup_st7567_erc13232_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 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_erc12864_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_erc12864_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_erc12864_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_96x65_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_96x65_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_96x65_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_96x65_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_96x65_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_96x65_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);
@@ -1303,8 +1407,11 @@ void u8g2_Setup_st7567_i2c_hem6432_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8
 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_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_yxd12832_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_yxd12832_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_yxd12832_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);
@@ -1315,11 +1422,29 @@ void u8g2_Setup_st7571_i2c_128x128_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8
 void u8g2_Setup_st7571_i2c_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_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_st7571_128x96_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_g12896_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_128x96_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_g12896_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_128x96_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_g12896_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_i2c_128x96_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_i2c_g12896_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_i2c_128x96_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_i2c_g12896_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_i2c_128x96_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_i2c_g12896_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7302_122x250_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7302_122x250_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7302_122x250_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_122x250_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_122x250_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_122x250_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_200x200_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_200x200_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_200x200_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_168x384_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_168x384_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st7305_168x384_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_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_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1335,6 +1460,9 @@ void u8g2_Setup_st7586s_ymc240160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x
 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_st7586s_md240128_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_md240128_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_md240128_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_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);
@@ -1347,6 +1475,12 @@ void u8g2_Setup_st75160_jm16096_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 void u8g2_Setup_st75160_i2c_jm16096_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75160_i2c_jm16096_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
 void u8g2_Setup_st75160_i2c_jm16096_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75161_jlx160160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75161_jlx160160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75161_jlx160160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75161_i2c_jlx160160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75161_i2c_jlx160160_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_st75161_i2c_jlx160160_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_jlx256128_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_wo256x128_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_jlx256128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1359,6 +1493,12 @@ void u8g2_Setup_st75256_i2c_jlx256128_2(u8g2_t *u8g2, const u8g2_cb_t *rotation,
 void u8g2_Setup_st75256_i2c_wo256x128_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_jlx256128_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_wo256x128_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_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_st75256_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_st75256_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_st75256_i2c_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_st75256_i2c_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_st75256_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_st75256_jlx256160_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_jlx256160m_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_jlx256160_alt_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1479,9 +1619,15 @@ void u8g2_Setup_t6963_160x80_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg
 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_t6963_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_t6963_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_t6963_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_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_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_128x72_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_128x72_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_128x72_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_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);
@@ -1492,11 +1638,17 @@ void u8g2_Setup_ssd1320_i2c_160x80_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8
 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_topwin_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_topwin_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_topwin_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_zjy_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_zjy_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_zjy_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_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);
@@ -1512,6 +1664,12 @@ void u8g2_Setup_ssd1362_206x36_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_m
 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_ssd1363_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_ssd1363_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_ssd1363_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_ssd1363_i2c_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_ssd1363_i2c_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_ssd1363_i2c_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_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_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
@@ -1533,6 +1691,9 @@ 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_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_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_sed1330_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_sed1330_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_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);
@@ -1557,6 +1718,15 @@ void u8g2_Setup_max7219_8x8_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_
 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_s1d15300_97x32_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_100x32_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_100x32i_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_97x32_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_100x32_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_100x32i_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_97x32_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_100x32_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_100x32i_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_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);
@@ -1581,6 +1751,13 @@ void u8g2_Setup_gp1294ai_256x48_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_
 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_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb);
+void u8g2_Setup_ssd1315_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_ssd1315_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_ssd1315_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_ssd1315_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_ssd1315_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_ssd1315_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_st7565_jlx12864g109pc_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb); // 2023年8月4日 晶联讯12864G-109-PC,12864G-139-P
 
 /* u8g2_d_setup.c generated code end */
@@ -1603,8 +1780,8 @@ uint8_t u8g2_NextPage(u8g2_t *u8g2);
 
 #ifdef U8G2_USE_DYNAMIC_ALLOC
 #define u8g2_SetBufferPtr(u8g2, buf) ((u8g2)->tile_buf_ptr = (buf));
-#define u8g2_GetBufferSize(u8g2) ((u8g2)->u8x8.display_info->tile_width * 8 * (u8g2)->tile_buf_height)
 #endif
+#define u8g2_GetBufferSize(u8g2) ((u8g2)->u8x8.display_info->tile_width * 8 * (u8g2)->tile_buf_height)
 #define u8g2_GetBufferPtr(u8g2) ((u8g2)->tile_buf_ptr)
 #define u8g2_GetBufferTileHeight(u8g2)	((u8g2)->tile_buf_height)
 #define u8g2_GetBufferTileWidth(u8g2)	(u8g2_GetU8x8(u8g2)->display_info->tile_width)
@@ -1682,6 +1859,12 @@ void u8g2_DrawDisc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad
 void u8g2_DrawEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option);
 void u8g2_DrawFilledEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option);
 
+
+/*==========================================*/
+/* u8g2_arc.c */
+void u8g2_DrawArc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t start, uint8_t end);
+
+
 /*==========================================*/
 /* u8g2_line.c */
 void u8g2_DrawLine(u8g2_t *u8g2, u8g2_uint_t x1, u8g2_uint_t y1, u8g2_uint_t x2, u8g2_uint_t y2);
@@ -1759,9 +1942,12 @@ void u8g2_SetFontMode(u8g2_t *u8g2, uint8_t is_transparent);
 
 uint8_t u8g2_IsGlyph(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_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, WARNING: use u8g2_GetGlyphXOffset() instead! */
+int8_t u8g2_GetXOffsetGlyph(u8g2_t *u8g2, uint16_t encoding);
+int8_t u8g2_GetXOffsetUTF8(u8g2_t *u8g2, const char *utf8);
 
 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);
@@ -1794,6 +1980,9 @@ void u8g2_SetFontRefHeightText(u8g2_t *u8g2);
 void u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2);
 void u8g2_SetFontRefHeightAll(u8g2_t *u8g2);
 
+void u8g2_DrawHB(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const unsigned char *data);
+
+
 /*==========================================*/
 /* u8log_u8g2.c */
 void u8g2_DrawLog(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8log_t *u8log);
@@ -1820,6 +2009,7 @@ uint8_t u8g2_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char
 void u8g2_SetupBuffer_SDL_128x64(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb);
 void u8g2_SetupBuffer_SDL_128x64_4(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb);
 void u8g2_SetupBuffer_SDL_128x64_1(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb);
+void u8g2_SetupBuffer_SDL_256x128(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb);
 
 /*==========================================*/
 /* u8x8_d_tga.c */
@@ -1880,6 +2070,8 @@ extern const uint8_t u8g2_font_7_Seg_33x19_mn[] U8G2_FONT_SECTION("u8g2_font_7_S
 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_tiny5_te[] U8G2_FONT_SECTION("u8g2_font_tiny5_te");
+extern const uint8_t u8g2_font_tiny5_t_all[] U8G2_FONT_SECTION("u8g2_font_tiny5_t_all");
 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");
@@ -2084,6 +2276,7 @@ extern const uint8_t u8g2_font_t0_11_mr[] U8G2_FONT_SECTION("u8g2_font_t0_11_mr"
 extern const uint8_t u8g2_font_t0_11_mn[] U8G2_FONT_SECTION("u8g2_font_t0_11_mn");
 extern const uint8_t u8g2_font_t0_11_me[] U8G2_FONT_SECTION("u8g2_font_t0_11_me");
 extern const uint8_t u8g2_font_t0_11_t_all[] U8G2_FONT_SECTION("u8g2_font_t0_11_t_all");
+extern const uint8_t u8g2_font_t0_11_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_11_t_symbol");
 extern const uint8_t u8g2_font_t0_11b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_11b_tf");
 extern const uint8_t u8g2_font_t0_11b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_11b_tr");
 extern const uint8_t u8g2_font_t0_11b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_11b_tn");
@@ -2100,6 +2293,7 @@ extern const uint8_t u8g2_font_t0_12_mf[] U8G2_FONT_SECTION("u8g2_font_t0_12_mf"
 extern const uint8_t u8g2_font_t0_12_mr[] U8G2_FONT_SECTION("u8g2_font_t0_12_mr");
 extern const uint8_t u8g2_font_t0_12_mn[] U8G2_FONT_SECTION("u8g2_font_t0_12_mn");
 extern const uint8_t u8g2_font_t0_12_me[] U8G2_FONT_SECTION("u8g2_font_t0_12_me");
+extern const uint8_t u8g2_font_t0_12_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_12_t_symbol");
 extern const uint8_t u8g2_font_t0_12b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_12b_tf");
 extern const uint8_t u8g2_font_t0_12b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_12b_tr");
 extern const uint8_t u8g2_font_t0_12b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_12b_tn");
@@ -2116,6 +2310,7 @@ extern const uint8_t u8g2_font_t0_13_mf[] U8G2_FONT_SECTION("u8g2_font_t0_13_mf"
 extern const uint8_t u8g2_font_t0_13_mr[] U8G2_FONT_SECTION("u8g2_font_t0_13_mr");
 extern const uint8_t u8g2_font_t0_13_mn[] U8G2_FONT_SECTION("u8g2_font_t0_13_mn");
 extern const uint8_t u8g2_font_t0_13_me[] U8G2_FONT_SECTION("u8g2_font_t0_13_me");
+extern const uint8_t u8g2_font_t0_13_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_13_t_symbol");
 extern const uint8_t u8g2_font_t0_13b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_13b_tf");
 extern const uint8_t u8g2_font_t0_13b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_13b_tr");
 extern const uint8_t u8g2_font_t0_13b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_13b_tn");
@@ -2132,6 +2327,7 @@ extern const uint8_t u8g2_font_t0_14_mf[] U8G2_FONT_SECTION("u8g2_font_t0_14_mf"
 extern const uint8_t u8g2_font_t0_14_mr[] U8G2_FONT_SECTION("u8g2_font_t0_14_mr");
 extern const uint8_t u8g2_font_t0_14_mn[] U8G2_FONT_SECTION("u8g2_font_t0_14_mn");
 extern const uint8_t u8g2_font_t0_14_me[] U8G2_FONT_SECTION("u8g2_font_t0_14_me");
+extern const uint8_t u8g2_font_t0_14_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_14_t_symbol");
 extern const uint8_t u8g2_font_t0_14b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_14b_tf");
 extern const uint8_t u8g2_font_t0_14b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_14b_tr");
 extern const uint8_t u8g2_font_t0_14b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_14b_tn");
@@ -2148,6 +2344,7 @@ extern const uint8_t u8g2_font_t0_15_mf[] U8G2_FONT_SECTION("u8g2_font_t0_15_mf"
 extern const uint8_t u8g2_font_t0_15_mr[] U8G2_FONT_SECTION("u8g2_font_t0_15_mr");
 extern const uint8_t u8g2_font_t0_15_mn[] U8G2_FONT_SECTION("u8g2_font_t0_15_mn");
 extern const uint8_t u8g2_font_t0_15_me[] U8G2_FONT_SECTION("u8g2_font_t0_15_me");
+extern const uint8_t u8g2_font_t0_15_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_15_t_symbol");
 extern const uint8_t u8g2_font_t0_15b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_15b_tf");
 extern const uint8_t u8g2_font_t0_15b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_15b_tr");
 extern const uint8_t u8g2_font_t0_15b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_15b_tn");
@@ -2164,6 +2361,7 @@ extern const uint8_t u8g2_font_t0_16_mf[] U8G2_FONT_SECTION("u8g2_font_t0_16_mf"
 extern const uint8_t u8g2_font_t0_16_mr[] U8G2_FONT_SECTION("u8g2_font_t0_16_mr");
 extern const uint8_t u8g2_font_t0_16_mn[] U8G2_FONT_SECTION("u8g2_font_t0_16_mn");
 extern const uint8_t u8g2_font_t0_16_me[] U8G2_FONT_SECTION("u8g2_font_t0_16_me");
+extern const uint8_t u8g2_font_t0_16_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_16_t_symbol");
 extern const uint8_t u8g2_font_t0_16b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_16b_tf");
 extern const uint8_t u8g2_font_t0_16b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_16b_tr");
 extern const uint8_t u8g2_font_t0_16b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_16b_tn");
@@ -2180,6 +2378,7 @@ extern const uint8_t u8g2_font_t0_17_mf[] U8G2_FONT_SECTION("u8g2_font_t0_17_mf"
 extern const uint8_t u8g2_font_t0_17_mr[] U8G2_FONT_SECTION("u8g2_font_t0_17_mr");
 extern const uint8_t u8g2_font_t0_17_mn[] U8G2_FONT_SECTION("u8g2_font_t0_17_mn");
 extern const uint8_t u8g2_font_t0_17_me[] U8G2_FONT_SECTION("u8g2_font_t0_17_me");
+extern const uint8_t u8g2_font_t0_17_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_17_t_symbol");
 extern const uint8_t u8g2_font_t0_17b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_17b_tf");
 extern const uint8_t u8g2_font_t0_17b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_17b_tr");
 extern const uint8_t u8g2_font_t0_17b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_17b_tn");
@@ -2196,6 +2395,7 @@ extern const uint8_t u8g2_font_t0_18_mf[] U8G2_FONT_SECTION("u8g2_font_t0_18_mf"
 extern const uint8_t u8g2_font_t0_18_mr[] U8G2_FONT_SECTION("u8g2_font_t0_18_mr");
 extern const uint8_t u8g2_font_t0_18_mn[] U8G2_FONT_SECTION("u8g2_font_t0_18_mn");
 extern const uint8_t u8g2_font_t0_18_me[] U8G2_FONT_SECTION("u8g2_font_t0_18_me");
+extern const uint8_t u8g2_font_t0_18_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_18_t_symbol");
 extern const uint8_t u8g2_font_t0_18b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_18b_tf");
 extern const uint8_t u8g2_font_t0_18b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_18b_tr");
 extern const uint8_t u8g2_font_t0_18b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_18b_tn");
@@ -2212,6 +2412,7 @@ extern const uint8_t u8g2_font_t0_22_mf[] U8G2_FONT_SECTION("u8g2_font_t0_22_mf"
 extern const uint8_t u8g2_font_t0_22_mr[] U8G2_FONT_SECTION("u8g2_font_t0_22_mr");
 extern const uint8_t u8g2_font_t0_22_mn[] U8G2_FONT_SECTION("u8g2_font_t0_22_mn");
 extern const uint8_t u8g2_font_t0_22_me[] U8G2_FONT_SECTION("u8g2_font_t0_22_me");
+extern const uint8_t u8g2_font_t0_22_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_22_t_symbol");
 extern const uint8_t u8g2_font_t0_22b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_22b_tf");
 extern const uint8_t u8g2_font_t0_22b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_22b_tr");
 extern const uint8_t u8g2_font_t0_22b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_22b_tn");
@@ -2220,6 +2421,40 @@ extern const uint8_t u8g2_font_t0_22b_mf[] U8G2_FONT_SECTION("u8g2_font_t0_22b_m
 extern const uint8_t u8g2_font_t0_22b_mr[] U8G2_FONT_SECTION("u8g2_font_t0_22b_mr");
 extern const uint8_t u8g2_font_t0_22b_mn[] U8G2_FONT_SECTION("u8g2_font_t0_22b_mn");
 extern const uint8_t u8g2_font_t0_22b_me[] U8G2_FONT_SECTION("u8g2_font_t0_22b_me");
+extern const uint8_t u8g2_font_t0_30_tf[] U8G2_FONT_SECTION("u8g2_font_t0_30_tf");
+extern const uint8_t u8g2_font_t0_30_tr[] U8G2_FONT_SECTION("u8g2_font_t0_30_tr");
+extern const uint8_t u8g2_font_t0_30_tn[] U8G2_FONT_SECTION("u8g2_font_t0_30_tn");
+extern const uint8_t u8g2_font_t0_30_te[] U8G2_FONT_SECTION("u8g2_font_t0_30_te");
+extern const uint8_t u8g2_font_t0_30_mf[] U8G2_FONT_SECTION("u8g2_font_t0_30_mf");
+extern const uint8_t u8g2_font_t0_30_mr[] U8G2_FONT_SECTION("u8g2_font_t0_30_mr");
+extern const uint8_t u8g2_font_t0_30_mn[] U8G2_FONT_SECTION("u8g2_font_t0_30_mn");
+extern const uint8_t u8g2_font_t0_30_me[] U8G2_FONT_SECTION("u8g2_font_t0_30_me");
+extern const uint8_t u8g2_font_t0_30_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_30_t_symbol");
+extern const uint8_t u8g2_font_t0_30b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_30b_tf");
+extern const uint8_t u8g2_font_t0_30b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_30b_tr");
+extern const uint8_t u8g2_font_t0_30b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_30b_tn");
+extern const uint8_t u8g2_font_t0_30b_te[] U8G2_FONT_SECTION("u8g2_font_t0_30b_te");
+extern const uint8_t u8g2_font_t0_30b_mf[] U8G2_FONT_SECTION("u8g2_font_t0_30b_mf");
+extern const uint8_t u8g2_font_t0_30b_mr[] U8G2_FONT_SECTION("u8g2_font_t0_30b_mr");
+extern const uint8_t u8g2_font_t0_30b_mn[] U8G2_FONT_SECTION("u8g2_font_t0_30b_mn");
+extern const uint8_t u8g2_font_t0_30b_me[] U8G2_FONT_SECTION("u8g2_font_t0_30b_me");
+extern const uint8_t u8g2_font_t0_40_tf[] U8G2_FONT_SECTION("u8g2_font_t0_40_tf");
+extern const uint8_t u8g2_font_t0_40_tr[] U8G2_FONT_SECTION("u8g2_font_t0_40_tr");
+extern const uint8_t u8g2_font_t0_40_tn[] U8G2_FONT_SECTION("u8g2_font_t0_40_tn");
+extern const uint8_t u8g2_font_t0_40_te[] U8G2_FONT_SECTION("u8g2_font_t0_40_te");
+extern const uint8_t u8g2_font_t0_40_mf[] U8G2_FONT_SECTION("u8g2_font_t0_40_mf");
+extern const uint8_t u8g2_font_t0_40_mr[] U8G2_FONT_SECTION("u8g2_font_t0_40_mr");
+extern const uint8_t u8g2_font_t0_40_mn[] U8G2_FONT_SECTION("u8g2_font_t0_40_mn");
+extern const uint8_t u8g2_font_t0_40_me[] U8G2_FONT_SECTION("u8g2_font_t0_40_me");
+extern const uint8_t u8g2_font_t0_40_t_symbol[] U8G2_FONT_SECTION("u8g2_font_t0_40_t_symbol");
+extern const uint8_t u8g2_font_t0_40b_tf[] U8G2_FONT_SECTION("u8g2_font_t0_40b_tf");
+extern const uint8_t u8g2_font_t0_40b_tr[] U8G2_FONT_SECTION("u8g2_font_t0_40b_tr");
+extern const uint8_t u8g2_font_t0_40b_tn[] U8G2_FONT_SECTION("u8g2_font_t0_40b_tn");
+extern const uint8_t u8g2_font_t0_40b_te[] U8G2_FONT_SECTION("u8g2_font_t0_40b_te");
+extern const uint8_t u8g2_font_t0_40b_mf[] U8G2_FONT_SECTION("u8g2_font_t0_40b_mf");
+extern const uint8_t u8g2_font_t0_40b_mr[] U8G2_FONT_SECTION("u8g2_font_t0_40b_mr");
+extern const uint8_t u8g2_font_t0_40b_mn[] U8G2_FONT_SECTION("u8g2_font_t0_40b_mn");
+extern const uint8_t u8g2_font_t0_40b_me[] U8G2_FONT_SECTION("u8g2_font_t0_40b_me");
 extern const uint8_t u8g2_font_open_iconic_all_1x_t[] U8G2_FONT_SECTION("u8g2_font_open_iconic_all_1x_t");
 extern const uint8_t u8g2_font_open_iconic_app_1x_t[] U8G2_FONT_SECTION("u8g2_font_open_iconic_app_1x_t");
 extern const uint8_t u8g2_font_open_iconic_arrow_1x_t[] U8G2_FONT_SECTION("u8g2_font_open_iconic_arrow_1x_t");
@@ -2613,6 +2848,7 @@ extern const uint8_t u8g2_font_iconquadpix_m_all[] U8G2_FONT_SECTION("u8g2_font_
 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_minimal3x3_tu[] U8G2_FONT_SECTION("u8g2_font_minimal3x3_tu");
 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");
@@ -2628,6 +2864,9 @@ extern const uint8_t u8g2_font_smolfont_te[] U8G2_FONT_SECTION("u8g2_font_smolfo
 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_micropixel_tf[] U8G2_FONT_SECTION("u8g2_font_micropixel_tf");
+extern const uint8_t u8g2_font_micropixel_tr[] U8G2_FONT_SECTION("u8g2_font_micropixel_tr");
+extern const uint8_t u8g2_font_micropixel_te[] U8G2_FONT_SECTION("u8g2_font_micropixel_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");
@@ -2960,6 +3199,7 @@ extern const uint8_t u8g2_font_unifont_t_tibetan[] U8G2_FONT_SECTION("u8g2_font_
 extern const uint8_t u8g2_font_unifont_t_urdu[] U8G2_FONT_SECTION("u8g2_font_unifont_t_urdu");
 extern const uint8_t u8g2_font_unifont_t_polish[] U8G2_FONT_SECTION("u8g2_font_unifont_t_polish");
 extern const uint8_t u8g2_font_unifont_t_devanagari[] U8G2_FONT_SECTION("u8g2_font_unifont_t_devanagari");
+extern const uint8_t u8g2_font_unifont_t_malayalam[] U8G2_FONT_SECTION("u8g2_font_unifont_t_malayalam");
 extern const uint8_t u8g2_font_unifont_t_arabic[] U8G2_FONT_SECTION("u8g2_font_unifont_t_arabic");
 extern const uint8_t u8g2_font_unifont_t_symbols[] U8G2_FONT_SECTION("u8g2_font_unifont_t_symbols");
 extern const uint8_t u8g2_font_unifont_h_symbols[] U8G2_FONT_SECTION("u8g2_font_unifont_h_symbols");
@@ -2971,6 +3211,9 @@ extern const uint8_t u8g2_font_unifont_t_weather[] U8G2_FONT_SECTION("u8g2_font_
 extern const uint8_t u8g2_font_unifont_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_unifont_t_chinese1");
 extern const uint8_t u8g2_font_unifont_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_unifont_t_chinese2");
 extern const uint8_t u8g2_font_unifont_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_unifont_t_chinese3");
+extern const uint8_t u8g2_font_unifont_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_unifont_t_gb2312");
+extern const uint8_t u8g2_font_unifont_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_unifont_t_gb2312a");
+extern const uint8_t u8g2_font_unifont_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_unifont_t_gb2312b");
 extern const uint8_t u8g2_font_unifont_t_japanese1[] U8G2_FONT_SECTION("u8g2_font_unifont_t_japanese1");
 extern const uint8_t u8g2_font_unifont_t_japanese2[] U8G2_FONT_SECTION("u8g2_font_unifont_t_japanese2");
 extern const uint8_t u8g2_font_unifont_t_japanese3[] U8G2_FONT_SECTION("u8g2_font_unifont_t_japanese3");
@@ -3014,6 +3257,39 @@ extern const uint8_t u8g2_font_wqy16_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_w
 extern const uint8_t u8g2_font_wqy16_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_gb2312");
 extern const uint8_t u8g2_font_wqy16_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_gb2312a");
 extern const uint8_t u8g2_font_wqy16_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_wqy16_t_gb2312b");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_tf[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_tf");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_tr[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_tr");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_tn[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_tn");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_te[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_te");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_t_all[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_t_all");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_t_chinese1");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_t_chinese2");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_t_chinese3");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_t_gb2312");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_t_gb2312a");
+extern const uint8_t u8g2_font_boutique_bitmap_7x7_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_7x7_t_gb2312b");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_tf[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_tf");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_tr[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_tr");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_tn[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_tn");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_te[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_te");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_t_all[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_t_all");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_t_chinese1");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_t_chinese2");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_t_chinese3");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_t_gb2312");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_t_gb2312a");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_t_gb2312b");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_tf[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_tf");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_tr[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_tr");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_tn[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_tn");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_te[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_te");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_t_all[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_t_all");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_t_chinese1[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_t_chinese1");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_t_chinese2[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_t_chinese2");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_t_chinese3[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_t_chinese3");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_t_gb2312[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_t_gb2312");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_t_gb2312a[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_t_gb2312a");
+extern const uint8_t u8g2_font_boutique_bitmap_9x9_bold_t_gb2312b[] U8G2_FONT_SECTION("u8g2_font_boutique_bitmap_9x9_bold_t_gb2312b");
 extern const uint8_t u8g2_font_b10_t_japanese1[] U8G2_FONT_SECTION("u8g2_font_b10_t_japanese1");
 extern const uint8_t u8g2_font_b10_t_japanese2[] U8G2_FONT_SECTION("u8g2_font_b10_t_japanese2");
 extern const uint8_t u8g2_font_b10_b_t_japanese1[] U8G2_FONT_SECTION("u8g2_font_b10_b_t_japanese1");
@@ -3747,6 +4023,14 @@ extern const uint8_t u8g2_font_logisoso58_tn[] U8G2_FONT_SECTION("u8g2_font_logi
 extern const uint8_t u8g2_font_logisoso62_tn[] U8G2_FONT_SECTION("u8g2_font_logisoso62_tn");
 extern const uint8_t u8g2_font_logisoso78_tn[] U8G2_FONT_SECTION("u8g2_font_logisoso78_tn");
 extern const uint8_t u8g2_font_logisoso92_tn[] U8G2_FONT_SECTION("u8g2_font_logisoso92_tn");
+extern const uint8_t u8g2_font_gulim11_t_korean1[] U8G2_FONT_SECTION("u8g2_font_gulim11_t_korean1");
+extern const uint8_t u8g2_font_gulim11_t_korean2[] U8G2_FONT_SECTION("u8g2_font_gulim11_t_korean2");
+extern const uint8_t u8g2_font_gulim12_t_korean1[] U8G2_FONT_SECTION("u8g2_font_gulim12_t_korean1");
+extern const uint8_t u8g2_font_gulim12_t_korean2[] U8G2_FONT_SECTION("u8g2_font_gulim12_t_korean2");
+extern const uint8_t u8g2_font_gulim14_t_korean1[] U8G2_FONT_SECTION("u8g2_font_gulim14_t_korean1");
+extern const uint8_t u8g2_font_gulim14_t_korean2[] U8G2_FONT_SECTION("u8g2_font_gulim14_t_korean2");
+extern const uint8_t u8g2_font_gulim16_t_korean1[] U8G2_FONT_SECTION("u8g2_font_gulim16_t_korean1");
+extern const uint8_t u8g2_font_gulim16_t_korean2[] U8G2_FONT_SECTION("u8g2_font_gulim16_t_korean2");
 extern const uint8_t u8g2_font_pressstart2p_8f[] U8G2_FONT_SECTION("u8g2_font_pressstart2p_8f");
 extern const uint8_t u8g2_font_pressstart2p_8r[] U8G2_FONT_SECTION("u8g2_font_pressstart2p_8r");
 extern const uint8_t u8g2_font_pressstart2p_8n[] U8G2_FONT_SECTION("u8g2_font_pressstart2p_8n");

+ 107 - 0
components/u8g2/u8g2_arc.c

@@ -0,0 +1,107 @@
+/*
+
+  u8g2_arc.c
+  
+  Contributed... see here: https://github.com/olikraus/u8g2/issues/2243
+
+  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 void u8g2_draw_arc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t start, uint8_t end)
+{
+  // Manage angle inputs
+  uint8_t full = (start == end);
+  uint8_t inverted = (start > end);
+  uint8_t a_start = inverted ? end : start;
+  uint8_t a_end = inverted ? start : end;
+
+  // Initialize variables
+  uint32_t ratio;
+  u8g2_int_t x = 0;
+  u8g2_int_t y = rad;
+  u8g2_int_t d = rad - 1;
+
+  // Trace arc radius with the Andres circle algorithm (process each pixel of a 1/8th circle of radius rad)
+  while (y >= x)
+  {
+    // Get the percentage of 1/8th circle drawn with a fast approximation of arctan(x/y)
+    ratio = x * 255 / y; // x/y [0..255]
+    ratio = ratio * (770195 - (ratio - 255) * (ratio + 941)) / 6137491; // arctan(x/y) [0..32]
+
+    // Fill the pixels of the 8 sections of the circle, but only on the arc defined by the angles (start and end)
+    if(full || ((ratio >= a_start && ratio < a_end) ^ inverted)) u8g2_DrawPixel(u8g2, x0 + y, y0 - x);
+    if(full || (((ratio + a_end) > 63 && (ratio + a_start) <= 63) ^ inverted)) u8g2_DrawPixel(u8g2, x0 + x, y0 - y);
+    if(full || (((ratio + 64) >= a_start && (ratio + 64) < a_end) ^ inverted)) u8g2_DrawPixel(u8g2, x0 - x, y0 - y);
+    if(full || (((ratio + a_end) > 127 && (ratio + a_start) <= 127) ^ inverted)) u8g2_DrawPixel(u8g2, x0 - y, y0 - x);
+    if(full || (((ratio + 128) >= a_start && (ratio + 128) < a_end) ^ inverted)) u8g2_DrawPixel(u8g2, x0 - y, y0 + x);
+    if(full || (((ratio + a_end) > 191 && (ratio + a_start) <= 191) ^ inverted)) u8g2_DrawPixel(u8g2, x0 - x, y0 + y);
+    if(full || (((ratio + 192) >= a_start && (ratio + 192) < a_end) ^ inverted)) u8g2_DrawPixel(u8g2, x0 + x, y0 + y);
+    if(full || (((ratio + a_end) > 255 && (ratio + a_start) <= 255) ^ inverted)) u8g2_DrawPixel(u8g2, x0 + y, y0 + x);
+
+    // Run Andres circle algorithm to get to the next pixel
+    if (d >= 2 * x)
+    {
+      d = d - 2 * x - 1;
+      x = x + 1;
+    }
+    else if (d < 2 * (rad - y))
+    {
+      d = d + 2 * y - 1;
+      y = y - 1;
+    }
+    else
+    {
+      d = d + 2 * (y - x - 1);
+      y = y - 1;
+      x = x + 1;
+    }
+  }
+}
+
+void u8g2_DrawArc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t start, uint8_t end)
+{
+  /* check for bounding box */
+#ifdef U8G2_WITH_INTERSECTION
+  {
+    if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 ) 
+      return;
+  }
+#endif /* U8G2_WITH_INTERSECTION */
+  
+  
+  /* draw arc */
+  u8g2_draw_arc(u8g2, x0, y0, rad, start, end);
+}
+
+

+ 59 - 2
components/u8g2/u8g2_bitmap.c

@@ -116,7 +116,9 @@ void u8g2_DrawHXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len,
   
   mask = 1;
   while(len > 0) {
-    if ( *b & mask ) {
+    uint8_t current_bit = (*b) & mask;
+#ifdef OLD
+    if ( current_bit ) {
       u8g2->draw_color = color;
       u8g2_DrawHVLine(u8g2, x, y, 1, 0);
     } else if ( u8g2->bitmap_transparency == 0 ) {
@@ -131,6 +133,32 @@ void u8g2_DrawHXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len,
       b++;
     }
     len--;
+#else
+    u8g2_uint_t run_length = 0;
+    // Determine the run length of consecutive bits with the same color
+    while (len > 0 && (current_bit == 0 ? (((*b) & mask) == 0) : (((*b) & mask) != 0 )  ))
+    {
+        run_length++;
+        x++;
+        mask <<= 1;
+        if (mask == 0)
+        {
+            mask = 1;
+            b++;
+        }
+        len--;
+    }
+    if (current_bit)
+    {
+        u8g2->draw_color = color;
+        u8g2_DrawHVLine(u8g2, x - run_length, y, run_length, 0);
+    }
+    else if (u8g2->bitmap_transparency == 0)
+    {
+        u8g2->draw_color = ncolor;
+        u8g2_DrawHVLine(u8g2, x - run_length, y, run_length, 0);
+    }
+#endif
   }
   u8g2->draw_color = color;
 }
@@ -174,7 +202,10 @@ void u8g2_DrawHXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len,
   mask = 1;
   while(len > 0)
   {
-    if( u8x8_pgm_read(b) & mask ) {
+    uint8_t current_bit = u8x8_pgm_read(b) & mask;
+//#define OLD
+#ifdef OLD
+    if ( current_bit ) {
       u8g2->draw_color = color;
       u8g2_DrawHVLine(u8g2, x, y, 1, 0);
     } else if( u8g2->bitmap_transparency == 0 ) {
@@ -190,6 +221,32 @@ void u8g2_DrawHXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len,
       b++;
     }
     len--;
+#else
+    u8g2_uint_t run_length = 0;
+    // Determine the run length of consecutive bits with the same color
+    while (len > 0 && (current_bit == 0 ? ((u8x8_pgm_read(b) & mask) == 0) : ((u8x8_pgm_read(b) & mask) != 0 )  ))
+    {
+        run_length++;
+        x++;
+        mask <<= 1;
+        if (mask == 0)
+        {
+            mask = 1;
+            b++;
+        }
+        len--;
+    }
+    if (current_bit)
+    {
+        u8g2->draw_color = color;
+        u8g2_DrawHVLine(u8g2, x - run_length, y, run_length, 0);
+    }
+    else if (u8g2->bitmap_transparency == 0)
+    {
+        u8g2->draw_color = ncolor;
+        u8g2_DrawHVLine(u8g2, x - run_length, y, run_length, 0);
+    }
+#endif
   }
   u8g2->draw_color = color;
 }

+ 264 - 33
components/u8g2/u8g2_d_memory.c

@@ -564,6 +564,39 @@ uint8_t *u8g2_m_12_2_f(uint8_t *page_cnt)
   return buf;
   #endif
 }
+uint8_t *u8g2_m_15_4_1(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 1;
+  return 0;
+  #else
+  static uint8_t buf[120];
+  *page_cnt = 1;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_15_4_2(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 2;
+  return 0;
+  #else
+  static uint8_t buf[240];
+  *page_cnt = 2;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_15_4_f(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 4;
+  return 0;
+  #else
+  static uint8_t buf[480];
+  *page_cnt = 4;
+  return buf;
+  #endif
+}
 uint8_t *u8g2_m_12_4_1(uint8_t *page_cnt)
 {
   #ifdef U8G2_USE_DYNAMIC_ALLOC
@@ -894,6 +927,39 @@ uint8_t *u8g2_m_18_21_f(uint8_t *page_cnt)
   return buf;
   #endif
 }
+uint8_t *u8g2_m_20_9_1(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 1;
+  return 0;
+  #else
+  static uint8_t buf[160];
+  *page_cnt = 1;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_20_9_2(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 2;
+  return 0;
+  #else
+  static uint8_t buf[320];
+  *page_cnt = 2;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_20_9_f(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 9;
+  return 0;
+  #else
+  static uint8_t buf[1440];
+  *page_cnt = 9;
+  return buf;
+  #endif
+}
 uint8_t *u8g2_m_11_6_1(uint8_t *page_cnt)
 {
   #ifdef U8G2_USE_DYNAMIC_ALLOC
@@ -1092,6 +1158,39 @@ uint8_t *u8g2_m_30_16_f(uint8_t *page_cnt)
   return buf;
   #endif
 }
+uint8_t *u8g2_m_32_16_1(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 1;
+  return 0;
+  #else
+  static uint8_t buf[256];
+  *page_cnt = 1;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_32_16_2(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 2;
+  return 0;
+  #else
+  static uint8_t buf[512];
+  *page_cnt = 2;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_32_16_f(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 16;
+  return 0;
+  #else
+  static uint8_t buf[4096];
+  *page_cnt = 16;
+  return buf;
+  #endif
+}
 uint8_t *u8g2_m_20_16_1(uint8_t *page_cnt)
 {
   #ifdef U8G2_USE_DYNAMIC_ALLOC
@@ -1224,39 +1323,6 @@ uint8_t *u8g2_m_30_20_f(uint8_t *page_cnt)
   return buf;
   #endif
 }
-uint8_t *u8g2_m_32_16_1(uint8_t *page_cnt)
-{
-  #ifdef U8G2_USE_DYNAMIC_ALLOC
-  *page_cnt = 1;
-  return 0;
-  #else
-  static uint8_t buf[256];
-  *page_cnt = 1;
-  return buf;
-  #endif
-}
-uint8_t *u8g2_m_32_16_2(uint8_t *page_cnt)
-{
-  #ifdef U8G2_USE_DYNAMIC_ALLOC
-  *page_cnt = 2;
-  return 0;
-  #else
-  static uint8_t buf[512];
-  *page_cnt = 2;
-  return buf;
-  #endif
-}
-uint8_t *u8g2_m_32_16_f(uint8_t *page_cnt)
-{
-  #ifdef U8G2_USE_DYNAMIC_ALLOC
-  *page_cnt = 16;
-  return 0;
-  #else
-  static uint8_t buf[4096];
-  *page_cnt = 16;
-  return buf;
-  #endif
-}
 uint8_t *u8g2_m_40_30_1(uint8_t *page_cnt)
 {
   #ifdef U8G2_USE_DYNAMIC_ALLOC
@@ -1422,6 +1488,105 @@ uint8_t *u8g2_m_17_9_f(uint8_t *page_cnt)
   return buf;
   #endif
 }
+uint8_t *u8g2_m_16_32_1(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 1;
+  return 0;
+  #else
+  static uint8_t buf[128];
+  *page_cnt = 1;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_16_32_2(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 2;
+  return 0;
+  #else
+  static uint8_t buf[256];
+  *page_cnt = 2;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_16_32_f(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 32;
+  return 0;
+  #else
+  static uint8_t buf[4096];
+  *page_cnt = 32;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_26_25_1(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 1;
+  return 0;
+  #else
+  static uint8_t buf[208];
+  *page_cnt = 1;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_26_25_2(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 2;
+  return 0;
+  #else
+  static uint8_t buf[416];
+  *page_cnt = 2;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_26_25_f(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 25;
+  return 0;
+  #else
+  static uint8_t buf[5200];
+  *page_cnt = 25;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_21_48_1(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 1;
+  return 0;
+  #else
+  static uint8_t buf[168];
+  *page_cnt = 1;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_21_48_2(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 2;
+  return 0;
+  #else
+  static uint8_t buf[336];
+  *page_cnt = 2;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_21_48_f(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 48;
+  return 0;
+  #else
+  static uint8_t buf[8064];
+  *page_cnt = 48;
+  return buf;
+  #endif
+}
 uint8_t *u8g2_m_48_17_1(uint8_t *page_cnt)
 {
   #ifdef U8G2_USE_DYNAMIC_ALLOC
@@ -1686,6 +1851,39 @@ uint8_t *u8g2_m_19_4_f(uint8_t *page_cnt)
   return buf;
   #endif
 }
+uint8_t *u8g2_m_16_9_1(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 1;
+  return 0;
+  #else
+  static uint8_t buf[128];
+  *page_cnt = 1;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_16_9_2(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 2;
+  return 0;
+  #else
+  static uint8_t buf[256];
+  *page_cnt = 2;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_16_9_f(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 9;
+  return 0;
+  #else
+  static uint8_t buf[1152];
+  *page_cnt = 9;
+  return buf;
+  #endif
+}
 uint8_t *u8g2_m_20_17_1(uint8_t *page_cnt)
 {
   #ifdef U8G2_USE_DYNAMIC_ALLOC
@@ -1983,6 +2181,39 @@ uint8_t *u8g2_m_1_1_f(uint8_t *page_cnt)
   return buf;
   #endif
 }
+uint8_t *u8g2_m_13_4_1(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 1;
+  return 0;
+  #else
+  static uint8_t buf[104];
+  *page_cnt = 1;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_13_4_2(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 2;
+  return 0;
+  #else
+  static uint8_t buf[208];
+  *page_cnt = 2;
+  return buf;
+  #endif
+}
+uint8_t *u8g2_m_13_4_f(uint8_t *page_cnt)
+{
+  #ifdef U8G2_USE_DYNAMIC_ALLOC
+  *page_cnt = 4;
+  return 0;
+  #else
+  static uint8_t buf[416];
+  *page_cnt = 4;
+  return buf;
+  #endif
+}
 uint8_t *u8g2_m_20_2_1(uint8_t *page_cnt)
 {
   #ifdef U8G2_USE_DYNAMIC_ALLOC

File diff ditekan karena terlalu besar
+ 766 - 106
components/u8g2/u8g2_d_setup.c


File diff ditekan karena terlalu besar
+ 676 - 146
components/u8g2/u8g2_fonts.c


+ 5 - 0
components/u8g2/u8g2_selection_list.c

@@ -63,6 +63,11 @@ void u8g2_DrawUTF8Line(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w
   /* calculate the width of the string in pixel */
   str_width = u8g2_GetUTF8Width(u8g2, s);
 
+#ifdef U8G2_BALANCED_STR_WIDTH_CALCULATION
+  /* subtract the first character offset added by the width calculation */
+  str_width -= u8g2_GetXOffsetUTF8(u8g2, s);
+#endif
+
   /* calculate delta d within the box */
   d = 0;
   if ( str_width < w )

+ 1 - 0
components/u8g2/u8log.c

@@ -147,6 +147,7 @@ void u8log_write_char(u8log_t *u8log, uint8_t c)
       u8log->is_redraw_all_required_for_next_nl = 0;
       u8log->cursor_y++;
       u8log->cursor_x = 0;
+      u8log_cursor_on_screen(u8log);  // 31 Aug 2024 https://github.com/olikraus/u8g2/issues/2319
       break;	
     case '\r':	// 13
       u8log->is_redraw_line = 1;

+ 45 - 3
components/u8g2/u8x8.h

@@ -646,6 +646,7 @@ void u8x8_SendF(u8x8_t * u8x8, const char *fmt, ...);
 #define U8X8_D1(d0)			(U8X8_MSG_CAD_SEND_DATA), (d0)
 
 #define U8X8_A4(a0,a1,a2,a3)		U8X8_A(a0), U8X8_A(a1), U8X8_A(a2), U8X8_A(a3)
+#define U8X8_A6(a0,a1,a2,a3,a4,a5)		U8X8_A(a0), U8X8_A(a1), U8X8_A(a2), U8X8_A(a3), U8X8_A(a4), U8X8_A(a5)
 #define U8X8_A8(a0,a1,a2,a3,a4,a5,a6,a7)	U8X8_A4((a0), (a1), (a2), (a3)), U8X8_A4((a4), (a5), (a6), (a7))
 
 
@@ -662,8 +663,9 @@ uint8_t u8x8_cad_001(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_cad_011(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_cad_100(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_cad_st7920_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
-uint8_t u8x8_cad_ssd13xx_fast_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);        /* CAD=001 */
+uint8_t u8x8_cad_011_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);     /* CAD=011 */
+uint8_t u8x8_cad_ssd13xx_fast_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);   /* CAD=001 */
 uint8_t u8x8_cad_st75256_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_cad_ld7032_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_cad_uc16xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);  /* CAD=001 */
@@ -800,6 +802,7 @@ void u8x8_SetupStdio(u8x8_t *u8x8);
 /* u8x8_d_sdl_128x64.c */
 void u8x8_Setup_SDL_128x64(u8x8_t *u8x8);
 void u8x8_Setup_SDL_240x160(u8x8_t *u8x8);
+void u8x8_Setup_SDL_256x128(u8x8_t *u8x8);
 int u8g_sdl_get_key(void);
 
 /*==========================================*/
@@ -832,7 +835,6 @@ void utf8_show(void);		/* show content of UTF-8 frame buffer */
 uint8_t u8x8_d_null_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 
 /* u8x8_d_XXX.c */
-uint8_t u8x8_d_custom_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1701_ea_dogs102(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);
@@ -844,8 +846,16 @@ uint8_t u8x8_d_ssd1306_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
 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_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);
+/* CSC ==> */
+uint8_t u8x8_d_ssd1309_128x128_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+/* <== CSC */
 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_ssd1312_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1312_120x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1312_120x28(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);
@@ -874,7 +884,9 @@ uint8_t u8x8_d_sh1107_hjr_oel1m0201_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg
 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_ch1120_128x160(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_128x32(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);
@@ -884,6 +896,7 @@ uint8_t u8x8_d_ls013b7dh03_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, v
 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_ls013b7dh05_144x168(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ls011b7dh03_160x68(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_erc16064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -910,17 +923,28 @@ uint8_t u8x8_d_st7567_64x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
 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_erc13232(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7567_erc12864(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_st7567_yxd12832(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7567_96x65(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_g12896(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7302_122x250(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7305_122x250(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7305_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_st7305_168x384(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);       /* https://github.com/olikraus/u8g2/issues/2661 */
 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_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_st7586s_md240128(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_st75161_jlx160160(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_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* https://github.com/olikraus/u8g2/issues/2702 */
 uint8_t u8x8_d_st75256_wo256x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx256160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_st75256_jlx256160m(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -942,6 +966,7 @@ uint8_t u8x8_d_t6963_128x64_alt(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
 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_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_t6963_128x160(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);
@@ -950,13 +975,18 @@ uint8_t u8x8_d_ssd1318_128x96_xcp(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, vo
 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_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_ssd1320_128x72(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_topwin_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_zjy_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_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_ssd1363_256x128(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_240x64(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);
@@ -975,6 +1005,7 @@ uint8_t u8x8_d_ssd1329_128x96_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
 uint8_t u8x8_d_ssd1329_96x96_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1601_128x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1601_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_uc1604_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1604_jlx19264(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1608_erc24064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1608_dem240064(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -988,6 +1019,9 @@ uint8_t u8x8_d_uc1611_ew50850(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
 uint8_t u8x8_d_uc1611_cg160160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* 160x160 */
 uint8_t u8x8_d_uc1617_jlx128128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_uc1611_ids4073(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); /* 256x128 */
+uint8_t u8x8_d_uc1628_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_uc1628_256x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_uc1628_256x32(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_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -999,6 +1033,7 @@ uint8_t u8x8_d_sbn1661_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
 uint8_t u8x8_d_sed1520_122x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_pcd8544_84x48(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_pcf8812_96x65(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_pcf8812_101x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_hx1230_96x68(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1606_172x72(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
 uint8_t u8x8_d_ssd1607_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
@@ -1021,12 +1056,16 @@ uint8_t u8x8_d_max7219_16x16(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
 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_s1d15300_lm6023(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_s1d15300_97x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_s1d15300_100x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
+uint8_t u8x8_d_s1d15300_100x32i(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_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_ssd1315_128x64_noname(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
 
 
@@ -1035,6 +1074,7 @@ uint8_t u8x8_d_st7565_jlx12864g109pc(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
 
 uint16_t u8x8_upscale_byte(uint8_t x) U8X8_NOINLINE;
 
+void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset) U8X8_NOINLINE;
 
 void u8x8_utf8_init(u8x8_t *u8x8);
 uint16_t u8x8_ascii_next(u8x8_t *u8x8, uint8_t b);
@@ -1059,6 +1099,8 @@ uint8_t u8x8_GetUTF8Len(u8x8_t *u8x8, const char *s);
 /*==========================================*/
 /* itoa procedures */
 const char *u8x8_u8toa(uint8_t v, uint8_t d);
+const char *u8x8_s8toa(int8_t v, uint8_t d);
+const char *u8x8_u8tox(uint8_t v, uint8_t d);
 const char *u8x8_u16toa(uint16_t v, uint8_t d);
 const char *u8x8_utoa(uint16_t v);
 

+ 2 - 2
components/u8g2/u8x8_8x8.c

@@ -58,8 +58,8 @@ void u8x8_SetFont(u8x8_t *u8x8, const uint8_t *font_8x8)
    encoding: glyph for which the data is requested (must be between 0 and 255)
    buf: pointer to 8 bytes
 */
-static void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset) U8X8_NOINLINE;
-static void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset) 
+void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset) U8X8_NOINLINE;
+void u8x8_get_glyph_data(u8x8_t *u8x8, uint8_t encoding, uint8_t *buf, uint8_t tile_offset) 
 {
   uint8_t first, last, tiles, i;
   uint16_t offset;

+ 53 - 6
components/u8g2/u8x8_cad.c

@@ -480,6 +480,7 @@ static void u8x8_i2c_data_transfer(u8x8_t *u8x8, uint8_t arg_int, void *arg_ptr)
 }
 
 /* classic version: will put a start/stop condition around each command and arg */
+/* implements CAD = 001 */
 uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
   uint8_t *p;
@@ -505,7 +506,53 @@ uint8_t u8x8_cad_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
       /* Unfortunately, this can not be handled in the byte level drivers, */
       /* so this is done here. Even further, only 24 bytes will be sent, */
       /* because there will be another byte (DC) required during the transfer */
-      p = arg_ptr;
+      p = (uint8_t *)arg_ptr;
+       while( arg_int > 24 )
+      {
+	u8x8_i2c_data_transfer(u8x8, 24, p);
+	arg_int-=24;
+	p+=24;
+      }
+      u8x8_i2c_data_transfer(u8x8, arg_int, p);
+      break;
+    case U8X8_MSG_CAD_INIT:
+      /* apply default i2c adr if required so that the start transfer msg can use this */
+      if ( u8x8->i2c_address == 255 )
+	u8x8->i2c_address = 0x078;
+      return u8x8->byte_cb(u8x8, msg, arg_int, arg_ptr);
+    case U8X8_MSG_CAD_START_TRANSFER:
+    case U8X8_MSG_CAD_END_TRANSFER:
+      /* cad transfer commands are ignored */
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+
+/* classic version: will put a start/stop condition around each command and arg */
+/* implements CAD = 011 for the SSD1363 */
+uint8_t u8x8_cad_011_ssd13xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  uint8_t *p;
+  switch(msg)
+  {
+    case U8X8_MSG_CAD_SEND_CMD:
+      u8x8_byte_StartTransfer(u8x8);
+      u8x8_byte_SendByte(u8x8, 0x000);
+      u8x8_byte_SendByte(u8x8, arg_int);
+      u8x8_byte_EndTransfer(u8x8);      
+      break;
+    case U8X8_MSG_CAD_SEND_ARG:
+      u8x8_byte_StartTransfer(u8x8);
+      u8x8_byte_SendByte(u8x8, 0x040);
+      u8x8_byte_SendByte(u8x8, arg_int);
+      u8x8_byte_EndTransfer(u8x8);      
+      break;
+    case U8X8_MSG_CAD_SEND_DATA:
+      p = (uint8_t *)arg_ptr;
        while( arg_int > 24 )
       {
 	u8x8_i2c_data_transfer(u8x8, 24, p);
@@ -575,7 +622,7 @@ uint8_t u8x8_cad_ssd13xx_fast_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, vo
       /* Unfortunately, this can not be handled in the byte level drivers, */
       /* so this is done here. Even further, only 24 bytes will be sent, */
       /* because there will be another byte (DC) required during the transfer */
-      p = arg_ptr;
+      p = (uint8_t *)arg_ptr;
        while( arg_int > 24 )
       {
 	u8x8_i2c_data_transfer(u8x8, 24, p);
@@ -627,7 +674,7 @@ uint8_t u8x8_cad_st75256_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
       break;
     case U8X8_MSG_CAD_SEND_DATA:
       /* see ssd13xx driver */
-      p = arg_ptr;
+      p = (uint8_t *)arg_ptr;
        while( arg_int > 24 )
       {
 	u8x8_i2c_data_transfer(u8x8, 24, p);
@@ -680,7 +727,7 @@ uint8_t u8x8_cad_ld7032_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
       /* Unfortunately, this can not be handled in the byte level drivers, */
       /* so this is done here. Even further, only 24 bytes will be sent, */
       /* because there will be another byte (DC) required during the transfer */
-      p = arg_ptr;
+      p = (uint8_t *)arg_ptr;
        while( arg_int > 24 )
       {
 	u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
@@ -764,7 +811,7 @@ uint8_t u8x8_cad_uc16xx_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
       in_transfer = 1;
       // is_data = 1;  // 20 Jun 2021: I assume that this is missing here
       
-      p = arg_ptr;
+      p = (uint8_t *)arg_ptr;
       while( arg_int > 24 )
       {
 	u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);
@@ -871,7 +918,7 @@ uint8_t u8x8_cad_uc1638_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
       in_transfer = 1;
       is_data = 1;
       
-      p = arg_ptr;
+      p = (uint8_t *)arg_ptr;
       while( arg_int > 24 )
       {
 	u8x8->byte_cb(u8x8, U8X8_MSG_CAD_SEND_DATA, 24, p);

+ 311 - 0
components/u8g2/u8x8_d_ch1120.c

@@ -0,0 +1,311 @@
+/*
+
+  u8x8_d_ch1120.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2018, olikraus@gmail.com
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without modification, 
+  are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this list 
+    of conditions and the following disclaimer.
+    
+  * Redistributions in binary form must reproduce the above copyright notice, this 
+    list of conditions and the following disclaimer in the documentation and/or other 
+    materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
+  
+*/
+
+
+#include "u8x8.h"
+
+/* 
+  code copyied from sh1107
+  ch1120: 160x160 controller from Sino Wealth
+  https://github.com/olikraus/u8g2/issues/2496
+*/
+
+
+
+static const uint8_t u8x8_d_ch1120_noname_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0af),		                /* display on */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ch1120_noname_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0ae),		                /* display off */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ch1120_160x160_noname_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0a0),				/* segment remap a0/a1*/
+  U8X8_C(0x0c0),				/* c0: scan dir normal, c8: reverse */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ch1120_160x160_noname_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0a1),				/* segment remap a0/a1*/
+  U8X8_C(0x0c8),				/* c0: scan dir normal, c8: reverse */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+static uint8_t u8x8_d_ch1120_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_ch1120_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_ch1120_64x128_noname_init_seq);    
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ch1120_noname_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ch1120_noname_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ch1120_160x160_noname_powersave0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ch1120_160x160_noname_powersave1_seq);
+	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+#ifdef U8X8_WITH_SET_CONTRAST
+    case U8X8_MSG_DISPLAY_SET_CONTRAST:
+      u8x8_cad_StartTransfer(u8x8);
+      u8x8_cad_SendCmd(u8x8, 0x081 );
+      u8x8_cad_SendArg(u8x8, arg_int );	/* ch1120 has range from 0 to 255 */
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+#endif
+    case U8X8_MSG_DISPLAY_DRAW_TILE:
+      u8x8_cad_StartTransfer(u8x8);
+      x = ((u8x8_tile_t *)arg_ptr)->x_pos;    
+      x *= 8;
+      x += u8x8->x_offset;
+
+      //u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
+
+      // set column address
+      u8x8_cad_SendCmd(u8x8, 0x010 | (x >> 4));
+      u8x8_cad_SendCmd(u8x8, 0x000 | ((x & 15))); 
+      
+      // set page address
+      u8x8_cad_SendCmd(u8x8, 0x0b0 ); 		// page cmd is a two byte command
+      u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos)); 
+    
+      do
+      {
+	c = ((u8x8_tile_t *)arg_ptr)->cnt;
+	ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+	u8x8_cad_SendData(u8x8, c*8, ptr); 	/* note: SendData can not handle more than 255 bytes */
+	arg_int--;
+      } while( arg_int > 0 );
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+/*==================================================*/
+
+#ifdef NOT_YET_REQUESTED
+/* 160x160 OLED */
+static const uint8_t u8x8_d_ch1120_160x160_noname_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+    
+  U8X8_C(0x0ae),		                /* display off */
+  U8X8_CA(0x0d5, 0x060),		/* clock divide ratio and oscillator frequency */
+  U8X8_CA(0x0a9, 0x003), 		/* set display resolution, 0=64x160, 1=96x160, 2=128x160, 3=160x160 */
+  U8X8_C(0x020),		                /* 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_ch1120_160x160_noname_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 60,
+  /* pre_chip_disable_wait_ns = */ 120,
+  /* reset_pulse_width_ms = */ 100, 	/* ch1120: 3 us */
+  /* post_reset_wait_ms = */ 100, /* sometimes OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 100,		/* ch1120: 100ns */
+  /* sck_pulse_width_ns = */ 100,	/* ch1120: 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,	/* ch1120: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 20,
+  /* tile_height = */ 20,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 160,
+  /* pixel_height = */ 160
+};
+
+uint8_t u8x8_d_ch1120_160x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    
+  if ( u8x8_d_ch1120_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_ch1120_160x160_noname_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ch1120_160x160_noname_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+#endif
+
+/*==================================================*/
+
+
+/* https://github.com/olikraus/u8g2/issues/2496, 128x160 OLED */
+static const uint8_t u8x8_d_ch1120_128x160_noname_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+    
+  U8X8_C(0x0ae),		                /* display off */
+  //U8X8_CAA(0x21, 0x00, 0x1f),           /* Set Column Start/End Address of Display RAM, mono mode */
+  //U8X8_CAA(0x22, 0x00, 0x4f),           /* Set Row Start/End Address of Display RAM, mono mode */
+  U8X8_CA(0x0a2, 0x000),		/* display start */
+  U8X8_CA(0x081, 0x08f), 		/* set contrast control */
+  U8X8_CA(0x0ac, 0x001),		/* mono mode, or 0x003???*/
+  U8X8_CA(0x020, 0x000),		/* addressing mode */
+  U8X8_C(0x0C8),		                /* scan direction */
+  U8X8_CA(0x0a3, 0x000),		/* display rotation */
+  
+  U8X8_CA(0x0a8, 0x07f),		/* multiplex ratio */
+  U8X8_CA(0x0d3, 0x010),		/* display offset */
+  
+  U8X8_CA(0x0d5, 0x01f),		/* clock divide ratio and oscillator frequency */
+  
+  U8X8_CA(0x048, 0x002),		/*  */
+  U8X8_CA(0x093, 0x002),		/*  */
+  U8X8_CA(0x0d8, 0x001),		/*  */
+  U8X8_CA(0x049, 0x006),		/*  */
+  U8X8_CA(0x0d9, 0x00f),		/*  */
+  U8X8_CA(0x094, 0x01f),		/*  */
+  U8X8_CA(0x04b, 0x004),		/*  */
+  U8X8_CA(0x0da, 0x000),		/*  */
+  U8X8_CA(0x0dc, 0x040),		/* VSEGM Deselect Level */
+  U8X8_CA(0x0ad, 0x002),		/*  */
+   
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const u8x8_display_info_t u8x8_ch1120_128x160_noname_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 = */ 100, 	/* ch1120: 3 us */
+  /* post_reset_wait_ms = */ 100, /* sometimes OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 100,		/* ch1120: 100ns */
+  /* sck_pulse_width_ns = */ 100,	/* ch1120: 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 = */ 40,	/* ch1120: 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_ch1120_128x160(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    
+  if ( u8x8_d_ch1120_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_ch1120_128x160_noname_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ch1120_128x160_noname_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+/*==================================================*/

+ 2 - 2
components/u8g2/u8x8_d_ks0108.c

@@ -110,7 +110,7 @@ static const u8x8_display_info_t u8x8_ks0108_128x64_display_info =
   
   /* post_chip_enable_wait_ns = */ 100,
   /* pre_chip_disable_wait_ns = */ 20,
-  /* reset_pulse_width_ms = */ 1, 
+  /* reset_pulse_width_ms = */ 5, 
   /* post_reset_wait_ms = */ 6, 		/* could be faster for the KS0108 */
   /* sda_setup_time_ns = */ 12,		
   /* sck_pulse_width_ns = */ 75,	/* KS0108: Not used */
@@ -217,7 +217,7 @@ static const u8x8_display_info_t u8x8_ks0108_192x64_display_info =
   
   /* post_chip_enable_wait_ns = */ 100,
   /* pre_chip_disable_wait_ns = */ 20,
-  /* reset_pulse_width_ms = */ 1, 
+  /* reset_pulse_width_ms = */ 5, 
   /* post_reset_wait_ms = */ 6, 		/* could be faster for the KS0108 */
   /* sda_setup_time_ns = */ 12,		
   /* sck_pulse_width_ns = */ 75,	/* KS0108: Not used */

+ 42 - 0
components/u8g2/u8x8_d_ls013b7dh03.c

@@ -121,6 +121,7 @@ uint8_t u8x8_d_ls013b7dh03_128x128(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_
   return 1;
 }
 
+/*===============================================*/
 
 static const u8x8_display_info_t u8x8_ls027b7dh01_400x240_display_info =
 {
@@ -158,6 +159,8 @@ uint8_t u8x8_d_ls027b7dh01_400x240(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_
   return 1;
 }
 
+/*===============================================*/
+
 static const u8x8_display_info_t u8x8_ls027b7dh01_m0_400x240_display_info =
 {
   /* chip_enable_level = */ 1,
@@ -194,6 +197,7 @@ uint8_t u8x8_d_ls027b7dh01_m0_400x240(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uin
   return 1;
 }
 
+/*===============================================*/
 
 static const u8x8_display_info_t u8x8_ls013b7dh05_144x168_display_info =
 {
@@ -231,4 +235,42 @@ uint8_t u8x8_d_ls013b7dh05_144x168(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_
   return 1;
 }
 
+/*===============================================*/
+/* https://github.com/olikraus/u8g2/issues/2210 */
+
+static const u8x8_display_info_t u8x8_ls011b7dh03_160x68_display_info =
+{
+  /* chip_enable_level = */ 1,
+  /* chip_disable_level = */ 0,
+  /* post_chip_enable_wait_ns = */ 50,
+  /* pre_chip_disable_wait_ns = */ 50,
+  /* reset_pulse_width_ms = */ 1,
+  /* post_reset_wait_ms = */ 6,
+  /* sda_setup_time_ns = */ 227,	/* 227 nsec according to the datasheet */		
+  /* sck_pulse_width_ns = */  255,	/* 450 nsec according to the datasheet */
+  /* sck_clock_hz = */ 1000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* spi_mode = */ 0,		/* changed from 2 to 0 (https://github.com/olikraus/u8g2/issues/1771) */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 100,
+  /* write_pulse_width_ns = */ 100,
+  /* tile_width = */ 20,
+  /* tile_height = */ 9,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 160,
+  /* pixel_height = */ 68
+};
+
+uint8_t u8x8_d_ls011b7dh03_160x68(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr)
+{
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ls011b7dh03_160x68_display_info);
+      break;
+    default:
+      return u8x8_d_ls013b7dh03_128x128(u8x8, msg, arg_int, arg_ptr);
+  }    
+  return 1;
+}
 

+ 138 - 0
components/u8g2/u8x8_d_pcf8812.c

@@ -60,6 +60,22 @@ static const uint8_t u8x8_d_pcf8812_96x65_init_seq[] = {
   U8X8_END()             			/* end of sequence */
 };
 
+
+static const uint8_t u8x8_d_pcf8812_101x64_init_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x21), // PowerON, ExtCommandSet
+  U8X8_C(0x09), // Internal HV-gen x3
+  U8X8_C(0xB7), // Set Vop
+  U8X8_C(0x16), // Bias n=2    //15
+  U8X8_C(0x06), // Temperature coeff 2
+  U8X8_C(0x20), // StandartCommandSet
+  U8X8_C(0x0C), // normal mode, display non-inverted
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+
 static const uint8_t u8x8_d_pcf8812_96x65_powersave0_seq[] = {
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
   U8X8_C(0x020),		                /* power on */
@@ -156,6 +172,86 @@ static uint8_t u8x8_d_pcf8812_96x65_generic(u8x8_t *u8x8, uint8_t msg, uint8_t a
 }
 
 
+static uint8_t u8x8_d_pcf8812_101x64_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  uint8_t x, c;
+  uint8_t *ptr;
+  switch(msg)
+  {
+    /* handled by the calling function
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info);
+      break;
+    */
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_101x64_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave1_seq);
+      break;
+/*
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip1_seq);
+	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+*/
+#ifdef U8X8_WITH_SET_CONTRAST
+    case U8X8_MSG_DISPLAY_SET_CONTRAST:
+      u8x8_cad_StartTransfer(u8x8);
+      u8x8_cad_SendCmd(u8x8, 0x021 );    /* command mode, extended function set */
+      u8x8_cad_SendArg(u8x8, (arg_int>>1)|0x80 );	/* 0..127 for contrast */
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+#endif
+    case U8X8_MSG_DISPLAY_DRAW_TILE:
+      u8x8_cad_StartTransfer(u8x8);
+      x = ((u8x8_tile_t *)arg_ptr)->x_pos;    
+      x *= 8;
+      x += u8x8->x_offset;
+    
+      u8x8_cad_SendCmd(u8x8, 0x020 );	/* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */
+      u8x8_cad_SendCmd(u8x8, 0x080 | x);
+      u8x8_cad_SendCmd(u8x8, 0x040 | ((u8x8_tile_t *)arg_ptr)->y_pos);
+      
+      do
+      {
+	c = ((u8x8_tile_t *)arg_ptr)->cnt;
+	ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+	u8x8_cad_SendData(u8x8, c*8, ptr); 	/* note: SendData can not handle more than 255 bytes */
+	/*
+	do
+	{
+	  u8x8_cad_SendData(u8x8, 8, ptr);
+	  ptr += 8;
+	  c--;
+	} while( c > 0 );
+	*/
+	arg_int--;
+      } while( arg_int > 0 );
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+
+
 static const u8x8_display_info_t u8x8_pcf8812_96x65_display_info =
 {
   /* chip_enable_level = */ 0,
@@ -190,4 +286,46 @@ uint8_t u8x8_d_pcf8812_96x65(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
     return u8x8_d_pcf8812_96x65_generic(u8x8, msg, arg_int, arg_ptr);
 }
 
+/* https://github.com/olikraus/u8g2/issues/2421 */
+static const u8x8_display_info_t u8x8_pcf8812_101x64_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 100,
+  /* pre_chip_disable_wait_ns = */ 100,
+  /* reset_pulse_width_ms = */ 100, 
+  /* post_reset_wait_ms = */ 100, 
+  /* sda_setup_time_ns = */ 100,	
+  /* sck_pulse_width_ns = */ 100,	
+  /* sck_clock_hz = */ 4000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 40,
+  /* write_pulse_width_ns = */ 150,	
+  /* tile_width = */ 13,
+  /* tile_height = */ 8,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 101,
+  /* pixel_height = */ 64
+};
+
+
+
+
+uint8_t u8x8_d_pcf8812_101x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
+    {
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_101x64_display_info);
+      return 1;
+    }
+    else if ( msg == U8X8_MSG_DISPLAY_INIT )
+    {
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_101x64_init_seq);    
+    }    
+    return u8x8_d_pcf8812_101x64_generic(u8x8, msg, arg_int, arg_ptr);
+}
 

+ 219 - 0
components/u8g2/u8x8_d_s1d15300.c

@@ -251,5 +251,224 @@ uint8_t u8x8_d_s1d15300_lm6023(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
 }
 
 /*================================================*/
+/* https://github.com/olikraus/u8g2/issues/2377 */
+
+static const u8x8_display_info_t u8x8_s1d15300_97x32_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 = */ 13,		/* width of 16*8=128 pixel */
+  /* tile_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 97,
+  /* pixel_height = */ 32
+};
+
+
+static const u8x8_display_info_t u8x8_s1d15300_100x32_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 = */ 13,		/* width of 16*8=128 pixel */
+  /* tile_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 100,
+  /* pixel_height = */ 32
+};
+
+static const u8x8_display_info_t u8x8_s1d15300_100x32i_display_info =
+{
+  /* chip_enable_level = */ 1,
+  /* chip_disable_level = */ 0,
+  
+  /* 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 = */ 13,		/* width of 16*8=128 pixel */
+  /* tile_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 100,
+  /* pixel_height = */ 32
+};
+
+
+static const uint8_t u8x8_d_s1d15300_100x32_init_seq[] = {
+
+
+    U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
+
+    U8X8_C(0x0e2), /* soft reset */
+
+    U8X8_C(0x0ae), /* display off */
+    U8X8_C(0x040), /* set display start line to 0 */
+    U8X8_C(0x0a0), /* ADC set to normal */
+    U8X8_C(0x0a6), /* Display normal */
+    U8X8_C(0x0a4), /* all point normal */
+
+    U8X8_C(0x0a2), /* LCD bias 1/8 */
+    U8X8_C(0x0c8), /* common output mode */
+    U8X8_C(0x02f), /* power, might be 0x02c */
+
+
+    U8X8_C(0x094), /* set contrast */
+    //U8X8_C(0x0af), /* display on */
+
+    U8X8_C(0x0b0), /* set page address */
+    U8X8_C(0x010), /* 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_97x32(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_97x32_display_info);
+	break;
+      case U8X8_MSG_DISPLAY_INIT:
+	u8x8_d_helper_display_init(u8x8);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_s1d15300_100x32_init_seq);
+	break;
+      case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 
+        /* needs to be fixed regarding a0/c0 */
+        /*
+	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;
+}
+
+
+uint8_t u8x8_d_s1d15300_100x32(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_100x32_display_info);
+	break;
+      case U8X8_MSG_DISPLAY_INIT:
+	u8x8_d_helper_display_init(u8x8);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_s1d15300_100x32_init_seq);
+	break;
+      case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 
+        /* needs to be fixed regarding a0/c0 */
+        /*
+	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;
+}
+
+uint8_t u8x8_d_s1d15300_100x32i(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_100x32i_display_info);
+	break;
+      case U8X8_MSG_DISPLAY_INIT:
+	u8x8_d_helper_display_init(u8x8);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_s1d15300_100x32_init_seq);
+	break;
+      case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+        /* needs to be fixed regarding a0/c0 */
+        /*
+	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;
+}
+
+
+/*================================================*/
 
 

+ 83 - 0
components/u8g2/u8x8_d_sed1330.c

@@ -264,6 +264,89 @@ uint8_t u8x8_d_ra8835_nhd_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, vo
   return 1;
 }
 
+/*=============================================*/
+/* issue 2518 https://github.com/olikraus/u8g2/issues/2518 */
+
+static const u8x8_display_info_t u8x8_sed1330_240x64_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 = */ 30,
+  /* tile_height = */ 8,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 240,
+  /* pixel_height = */ 64
+};
+
+static const uint8_t u8x8_d_sed1330_240x64_init_seq[] = {
+  U8X8_DLY(100),
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_DLY(100),
+
+  /* system init command, see also u8x8_d_sed1330_powersave0_seq */
+  U8X8_CA(0x040, 0x030),		/* sys init (0x040) with one arg, where 0x030 is a wild guess */
+  /* system init has total 8 parameters, so 7 more are here */
+  U8X8_A(0x087),				/* no idea here... WF (topmost bit) is set to one because it is suggested in the datasheet, lowest 3 bits refer to text mode only */
+  U8X8_A(0x007),				/* FY: height of a char+1, does not matter here (hopefully), because we use graphics mode only */
+  U8X8_A(0x01d),				/* C/R: this could be the number of horizontal bytes - 1 (Value confirmed with app notes p41) */
+  U8X8_A(0x050),					/* TC/R: According to app notes fOSC=6Mhz fFF=70Hz --> TC/R = 74d*/
+  U8X8_A(0x03f),				/* L/F: Lines per frame - 1, probably this is the height of the display - 1 (value confirmed with app notes p41)*/
+  U8X8_A(0x01e),				/* Low byte of the virtual screen size. (Value confirmed with app notes p41)   */
+  U8X8_A(0),					/* High byte of the virtual screen size, see also section 9.1.2 */
+	
+  U8X8_C(0x044),				/* SCROLL */
+  U8X8_A(0x000),				
+  U8X8_A(0x000),				
+  U8X8_A(0x080),
+  U8X8_A(0x000),
+  U8X8_A(0x040),
+  U8X8_A(0x080),
+  U8X8_A(0x000),
+  U8X8_A(0x000),
+  U8X8_A(0x000),
+  U8X8_A(0x000),
+	
+  U8X8_CA(0x05a, 0),			/* HDOT SCR: Horizontal dotwise scroll... set to 0 */
+	
+  U8X8_CA(0x05b, 0x0c),			/* OVLAY: 2-layer, all graphics, OR between layer 1 and 2 */
+
+
+  U8X8_DLY(100),
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_DLY(100),
+};
+
+
+uint8_t u8x8_d_sed1330_240x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_sed1330_240x64_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_sed1330_240x64_init_seq);
+      u8x8_SendF(u8x8, "caaaaaaaa", 0x40, 0x30, 0x87, 0x07, 0x1d, 0x50, 0x3f, 0x1e, 0x00);  /* send init again, issue 2518 https://github.com/olikraus/u8g2/issues/2518 */
+      break;
+    default:
+      return u8x8_d_sed1330_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
 
 
 /*=============================================*/

+ 10 - 2
components/u8g2/u8x8_d_sh1107.c

@@ -465,6 +465,14 @@ uint8_t u8x8_d_sh1107_hjr_oel1m0201_96x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg
 /*==================================================*/
 /* 128x128 OLED: this display has a very strange x offset */
 
+/* 
+6 Feb 2025: 
+There is an issue 
+https://github.com/olikraus/u8g2/issues/2581#issuecomment-2628394758 
+Looks like there are displays where the x offset must be 0
+*/
+
+
 /* sequence taken over from 64x128 sequence, because it seems to work mostly */
 static const uint8_t u8x8_d_sh1107_128x128_init_seq[] = {
     
@@ -516,8 +524,8 @@ static const u8x8_display_info_t u8x8_sh1107_128x128_display_info =
   /* write_pulse_width_ns = */ 150,	/* sh1107: cycle time is 300ns, so use 300/2 = 150 */
   /* tile_width = */ 16,
   /* tile_height = */ 16,
-  /* default_x_offset = */ 0,
-  /* flipmode_x_offset = */ 0,
+  /* default_x_offset = */ 96,
+  /* flipmode_x_offset = */ 96,
   /* pixel_width = */ 128,
   /* pixel_height = */ 128
 };

+ 1 - 1
components/u8g2/u8x8_d_sh1108.c

@@ -232,7 +232,7 @@ static const uint8_t u8x8_d_sh1108_128x160_noname_init_seq[] = {
     
   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_CA(0x0a9, 0x002), 		/* 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*/

+ 119 - 29
components/u8g2/u8x8_d_ssd1309.c

@@ -33,44 +33,40 @@
   
 */
 
-
 #include "u8x8.h"
 
-
-
-
 static const uint8_t u8x8_d_ssd1309_powersave0_seq[] = {
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
-  U8X8_C(0x0af),		                /* display on */
-  U8X8_END_TRANSFER(),             	/* disable chip */
-  U8X8_END()             			/* end of sequence */
+  U8X8_C(0x0af),		                  /* display on */
+  U8X8_END_TRANSFER(),             	  /* disable chip */
+  U8X8_END()             			        /* end of sequence */
 };
 
 static const uint8_t u8x8_d_ssd1309_powersave1_seq[] = {
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
-  U8X8_C(0x0ae),		                /* display off */
-  U8X8_END_TRANSFER(),             	/* disable chip */
-  U8X8_END()             			/* end of sequence */
+  U8X8_C(0x0ae),		                  /* display off */
+  U8X8_END_TRANSFER(),             	  /* disable chip */
+  U8X8_END()             			        /* end of sequence */
 };
 
-static const uint8_t u8x8_d_ssd1309_128x64_flip0_seq[] = {
+/* ==> CSC rename u8x8_d_ssd1309_128x64_flip0_seq => u8x8_d_ssd1309_flip0_seq <== */
+static const uint8_t u8x8_d_ssd1309_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 */
+  U8X8_C(0x0a1),				              /* segment remap a0/a1*/
+  U8X8_C(0x0c8),				              /* c0: scan dir normal, c8: reverse */
+  U8X8_END_TRANSFER(),             	  /* disable chip */
+  U8X8_END()             			        /* end of sequence */
 };
 
-static const uint8_t u8x8_d_ssd1309_128x64_flip1_seq[] = {
+/* ==> CSC rename u8x8_d_ssd1309_128x64_flip1_seq => u8x8_d_ssd1309_flip1_seq <== */
+static const uint8_t u8x8_d_ssd1309_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 */
+  U8X8_C(0x0a0),				              /* segment remap a0/a1*/
+  U8X8_C(0x0c0),				              /* c0: scan dir normal, c8: reverse */
+  U8X8_END_TRANSFER(),             	  /* disable chip */
+  U8X8_END()             			        /* end of sequence */
 };
 
-
-
 static uint8_t u8x8_d_ssd1309_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
   uint8_t x, c;
@@ -160,7 +156,6 @@ static const uint8_t u8x8_d_ssd1309_128x64_noname_init_seq[] = {
     
   U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
   
-  
   U8X8_C(0x0ae),		                /* display off */
   U8X8_CA(0x0d5, 0x0a0),		/* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
   //U8X8_CA(0x0a8, 0x03f),		/* multiplex ratio */
@@ -191,6 +186,41 @@ static const uint8_t u8x8_d_ssd1309_128x64_noname_init_seq[] = {
   U8X8_END()             			/* end of sequence */
 };
 
+/* CSC ==> */
+static const uint8_t u8x8_d_ssd1309_128x128_noname_init_seq[] = {
+
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+
+  U8X8_C(0x0ae),		                  /* display off */
+  U8X8_CA(0x0d5, 0x0a0),		          /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */
+  U8X8_CA(0x0a8, 0x07f),              /* multiplex ratio */ /* 128 Zeilen  0x07f, 64 Zeilen 0x03f */
+  U8X8_C(0x040),            	        /* set display start line to 0 */
+  U8X8_CA(0x020, 0x002),		          /* 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, 0x06f), 		          /* [2] set contrast control */
+  U8X8_CA(0x0d9, 0x0d3), 		          /* [2] pre-charge period 0x022/f1*/
+  U8X8_CA(0x0db, 0x020), 		          /* vcomh deselect level */
+  // if vcomh is 0, then this will give the biggest range for contrast control issue #98
+  // restored the old values for the noname constructor, because vcomh=0 will not work for all OLEDs, #116
+
+  U8X8_C(0x02e),				              /* Deactivate scroll */
+  U8X8_C(0x0a4),				              /* output ram to display */
+  U8X8_C(0x0a6),				              /* none inverted normal display mode */
+
+  //U8X8_C(0x0af),		                /* display on */
+
+  U8X8_END_TRANSFER(),             	  /* disable chip */
+  U8X8_END()             			        /* end of sequence */
+};
+/* <== CSC */
 
 uint8_t u8x8_d_ssd1309_128x64_noname2(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
@@ -203,12 +233,12 @@ uint8_t u8x8_d_ssd1309_128x64_noname2(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int
     case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
       if ( arg_int == 0 )
       {
-	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip0_seq);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_flip0_seq);
 	u8x8->x_offset = u8x8->display_info->default_x_offset;
       }
       else
       {
-	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip1_seq);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_flip1_seq);
 	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
       }
       break;
@@ -254,6 +284,32 @@ static const u8x8_display_info_t u8x8_ssd1309_128x64_noname0_display_info =
   /* pixel_height = */ 64
 };
 
+/* CSC ==> */
+static const u8x8_display_info_t u8x8_ssd1309_128x128_noname0_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+
+  /* post_chip_enable_wait_ns = */ 20,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 100, 	/* SSD1306: 3 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
+  /* sck_clock_hz = */ 4000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 40,
+  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 16,
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 128
+};
+/* <== CSC */
+
 uint8_t u8x8_d_ssd1309_128x64_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
     
@@ -265,12 +321,12 @@ uint8_t u8x8_d_ssd1309_128x64_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int
     case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
       if ( arg_int == 0 )
       {
-	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip0_seq);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_flip0_seq);
 	u8x8->x_offset = u8x8->display_info->default_x_offset;
       }
       else
       {
-	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip1_seq);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_flip1_seq);
 	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
       }
       break;
@@ -287,6 +343,40 @@ uint8_t u8x8_d_ssd1309_128x64_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int
   return 1;
 }
 
+/* CSC ==> */
+uint8_t u8x8_d_ssd1309_128x128_noname0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+
+  if ( u8x8_d_ssd1309_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+    return 1;
+
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	    u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_flip0_seq);
+	    u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	    u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_flip1_seq);
+	    u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x128_noname_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1309_128x128_noname0_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+/* <== CSC */
 
 /*=================================================*/
 /*
@@ -352,12 +442,12 @@ uint8_t u8x8_d_ssd1306_102x64_ea_oleds102(u8x8_t *u8x8, uint8_t msg, uint8_t arg
     case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
       if ( arg_int == 0 )
       {
-	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip0_seq);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_flip0_seq);
 	u8x8->x_offset = u8x8->display_info->default_x_offset;
       }
       else
       {
-	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_128x64_flip1_seq);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1309_flip1_seq);
 	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
       }
       break;

+ 354 - 0
components/u8g2/u8x8_d_ssd1312.c

@@ -0,0 +1,354 @@
+/*
+
+  u8x8_d_ssd1312.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2024, 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.  
+
+
+  NOTE: There is another SSD1312 128x64 in u8x8_d_ssd1306_128x64_noname.c
+
+*/
+
+
+#include "u8x8.h"
+
+
+static const uint8_t u8x8_d_ssd1312_128x32_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0af),		                /* display on */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1312_128x32_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0ae),		                /* display off */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+
+static uint8_t u8x8_d_ssd1312_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  uint8_t x, c;
+  uint8_t *ptr;
+  switch(msg)
+  {
+    /* handled by the calling function
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
+      break;
+    */
+    /* handled by the calling function
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);    
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x32_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_128x32_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 );	/* ssd1306 has range from 0 to 255 */
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+#endif
+    case U8X8_MSG_DISPLAY_DRAW_TILE:
+      u8x8_cad_StartTransfer(u8x8);
+      x = ((u8x8_tile_t *)arg_ptr)->x_pos;    
+      x *= 8;
+      x += u8x8->x_offset;
+    
+      u8x8_cad_SendCmd(u8x8, 0x040 );	/* set line offset to 0 */
+    
+      u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
+      u8x8_cad_SendArg(u8x8, 0x000 | ((x&15)));					/* probably wrong, should be SendCmd */
+      u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));	/* probably wrong, should be SendCmd */
+
+    
+      do
+      {
+	c = ((u8x8_tile_t *)arg_ptr)->cnt;
+	ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+	u8x8_cad_SendData(u8x8, c*8, ptr); 	/* note: SendData can not handle more than 255 bytes */
+	/*
+	do
+	{
+	  u8x8_cad_SendData(u8x8, 8, ptr);
+	  ptr += 8;
+	  c--;
+	} while( c > 0 );
+	*/
+	arg_int--;
+      } while( arg_int > 0 );
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+static const uint8_t u8x8_d_ssd1312_128x32_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_128x32_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0a0),				/* segment remap a0/a1*/
+  U8X8_C(0x0c8),				/* c0: scan dir normal, c8: reverse */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1312_128x32_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 */
+  
+  /* 11 Aug 2025: The value below doesn't mach the bits 4 and 5, actually 0x12 would enable the alternate odd/even remapping */
+  /* probably the correct configuration value should be 0x00, see https://github.com/olikraus/u8g2/issues/2690 ??? */
+  U8X8_CA(0x0da, 0x012),		/* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
+
+  U8X8_CA(0x0d3, 0x030),		/* line shift by 3*16 = 48 */
+
+  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 u8x8_display_info_t u8x8_ssd1312_128x32_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 20,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 100, 	/* SSD1306: 3 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
+  /* sck_clock_hz = */ 8000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 40,
+  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 16,
+  /* tile_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 32
+};
+
+/* https://github.com/olikraus/u8g2/issues/2368 128x32 */
+
+
+uint8_t u8x8_d_ssd1312_128x32(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_128x32_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_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_ssd1312_128x32_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1312_128x32_display_info);
+      break;
+    default:
+      if ( u8x8_d_ssd1312_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+        return 1;
+  }
+  return 1;
+}
+
+/*====================================*/
+/* issue https://github.com/olikraus/u8g2/issues/2483 */
+
+static const u8x8_display_info_t u8x8_ssd1312_120x32_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 20,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 100, 	/* SSD1306: 3 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
+  /* sck_clock_hz = */ 8000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 40,
+  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 15,
+  /* tile_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 120,
+  /* pixel_height = */ 32
+};
+
+
+uint8_t u8x8_d_ssd1312_120x32(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_128x32_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_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_ssd1312_128x32_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1312_120x32_display_info);
+      break;
+    default:
+      if ( u8x8_d_ssd1312_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+        return 1;
+  }
+  return 1;
+}
+
+
+
+
+
+static const u8x8_display_info_t u8x8_ssd1312_120x28_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 20,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 100, 	/* SSD1306: 3 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
+  /* sck_clock_hz = */ 8000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215) */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 40,
+  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 15,
+  /* tile_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 120,
+  /* pixel_height = */ 28
+};
+
+
+
+
+uint8_t u8x8_d_ssd1312_120x28(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_128x32_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1312_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_ssd1312_128x32_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1312_120x28_display_info);
+      break;
+    default:
+      if ( u8x8_d_ssd1312_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+        return 1;
+  }
+  return 1;
+}
+

+ 215 - 0
components/u8g2/u8x8_d_ssd1315_128x64_noname.c

@@ -0,0 +1,215 @@
+/*
+
+  u8x8_d_ssd1315_128x64_noname.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2016, olikraus@gmail.com
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without modification, 
+  are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this list 
+    of conditions and the following disclaimer.
+    
+  * Redistributions in binary form must reproduce the above copyright notice, this 
+    list of conditions and the following disclaimer in the documentation and/or other 
+    materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
+  
+*/
+
+#include "u8x8.h"
+
+/* more or less generic setup of all these small OLEDs */
+static const uint8_t u8x8_d_ssd1315_128x64_noname_init_seq[] = {
+  U8X8_START_TRANSFER(),  /* enable chip, delay is part of the transfer start */
+
+  U8X8_C(0x0ae),          /* display off */
+  U8X8_CA(0x0d5, 0x090),  /* Set Display Clock Divide */
+  U8X8_CA(0x0a8, 0x03f),  /* multiplex ratio */
+  U8X8_CA(0x0d3, 0x000),  /* display offset */
+  U8X8_C(0x040),          /* set display start line to 0 */
+  U8X8_C(0x0a1),          /* segment remap a0/a1*/
+  U8X8_C(0x0c8),          /* c0: scan dir normal, c8: reverse */
+  U8X8_CA(0x0da, 0x012),  /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */
+  U8X8_CA(0x081, 0x07f),  /* set contrast control */
+  U8X8_CA(0x0d9, 0x022),  /* pre-charge period 0x022/f1*/
+  U8X8_CA(0x0db, 0x030),  /* vcomh deselect level */  
+  U8X8_C(0x0a4),          /* output ram to display */
+  U8X8_C(0x0a6),          /* none inverted normal display mode */
+  U8X8_CA(0x0ad, 0x010),  /* Select External or Internal Iref: 0x20 External Iref = 200kΩ = (9 - 3) / 30uA, 0x10 or 0x30 Internal Iref */
+  U8X8_CA(0x08d, 0x014),  /* charge pump setting: 0x14 enable, VCC=7.5V, 0x00 disable */
+
+  U8X8_END_TRANSFER(),    /* disable chip */
+  U8X8_END()              /* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1315_128x64_noname_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),  /* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0af),          /* display on */
+  U8X8_END_TRANSFER(),    /* disable chip */
+  U8X8_END()              /* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1315_128x64_noname_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),  /* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0ae),          /* display off */
+  U8X8_END_TRANSFER(),    /* disable chip */
+  U8X8_END()              /* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1315_128x64_noname_flip0_seq[] = {
+  U8X8_START_TRANSFER(),  /* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0a1),          /* segment remap a0/a1*/
+  U8X8_C(0x0c8),          /* c0: scan dir normal, c8: reverse */
+  U8X8_END_TRANSFER(),    /* disable chip */
+  U8X8_END()              /* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1315_128x64_noname_flip1_seq[] = {
+  U8X8_START_TRANSFER(),  /* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0a0),          /* segment remap a0/a1*/
+  U8X8_C(0x0c0),          /* c0: scan dir normal, c8: reverse */
+  U8X8_END_TRANSFER(),    /* disable chip */
+  U8X8_END()              /* end of sequence */
+};
+
+
+static uint8_t u8x8_d_ssd1315_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  uint8_t x, c;
+  uint8_t *ptr;
+  switch(msg)
+  {
+    /* handled by the calling function
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1306_128x64_noname_display_info);
+      break;
+    */
+    /* handled by the calling function
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1306_128x64_noname_init_seq);    
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	    u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1315_128x64_noname_powersave0_seq);
+      else
+	    u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1315_128x64_noname_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+        u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1315_128x64_noname_flip0_seq);
+        u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+        u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1315_128x64_noname_flip1_seq);
+        u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+#ifdef U8X8_WITH_SET_CONTRAST
+  case U8X8_MSG_DISPLAY_SET_CONTRAST:
+    u8x8_cad_StartTransfer(u8x8);
+    u8x8_cad_SendCmd(u8x8, 0x081 );
+    u8x8_cad_SendArg(u8x8, arg_int );	/* ssd1306 has range from 0 to 255 */
+    u8x8_cad_EndTransfer(u8x8);
+    break;
+#endif
+  case U8X8_MSG_DISPLAY_DRAW_TILE:
+    u8x8_cad_StartTransfer(u8x8);
+    x = ((u8x8_tile_t *)arg_ptr)->x_pos;    
+    x *= 8;
+    x += u8x8->x_offset;
+
+    u8x8_cad_SendCmd(u8x8, 0x040 ); /* set line offset to 0 */
+
+    u8x8_cad_SendCmd(u8x8, 0x010 | (x>>4) );
+    u8x8_cad_SendArg(u8x8, 0x000 | ((x&15))); /* probably wrong, should be SendCmd */
+    u8x8_cad_SendArg(u8x8, 0x0b0 | (((u8x8_tile_t *)arg_ptr)->y_pos));  /* probably wrong, should be SendCmd */
+
+    do
+    {
+      c = ((u8x8_tile_t *)arg_ptr)->cnt;
+      ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+      u8x8_cad_SendData(u8x8, c*8, ptr);  /* note: SendData can not handle more than 255 bytes */
+    /*
+    do
+    {
+      u8x8_cad_SendData(u8x8, 8, ptr);
+      ptr += 8;
+      c--;
+    } while( c > 0 );
+    */
+	    arg_int--;
+    } while( arg_int > 0 );
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+static const u8x8_display_info_t u8x8_ssd1315_128x64_noname_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 20,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 100, 	/* SSD1306: 3 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* SSD1306: 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* SSD1306: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
+  /* sck_clock_hz = */ 8000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 40,
+  /* write_pulse_width_ns = */ 150,	/* SSD1306: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 16,
+  /* tile_height = */ 8,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 64
+};
+
+uint8_t u8x8_d_ssd1315_128x64_noname(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    
+  if ( u8x8_d_ssd1315_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_ssd1315_128x64_noname_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1315_128x64_noname_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}

+ 166 - 0
components/u8g2/u8x8_d_ssd1320.c

@@ -720,3 +720,169 @@ uint8_t u8x8_d_ssd1320_160x80(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *
   }
   return 1;
 }
+
+
+/*=========================================================*/
+/* https://github.com/olikraus/u8g2/issues/2565 */
+/* 128x72, https://www.buydisplay.com/128x72-grayscale-oled-spi-white-0-72-inch-arduino-raspberry-pi */
+
+static const uint8_t u8x8_d_ssd1320_128x72_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, 0x2c),        /* display offset WARNING: ALSO ASSIGN THIS IN THE INIT SEQ */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1320_128x72_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, 0x74),        /* display offset */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const u8x8_display_info_t u8x8_d_ssd1320_128x72_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 = */ 16,		/* 128 */
+  /* tile_height = */ 9,                /* 72 */
+  /* default_x_offset = */ 16,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 72
+};
+
+/*      from the buydisplay.com example code for the 8051:
+        Contrast_level=0xDF
+
+	OLED_WR_Byte(0xae,OLED_CMD);//Set y Off
+	OLED_WR_Byte(0xD5,OLED_CMD);//Set Display Clock Divide Ratio/Oscillator Frequency
+	OLED_WR_Byte(0x11,OLED_CMD); 
+	OLED_WR_Byte(0xA8,OLED_CMD);//Set Multiplex Ratio 
+	OLED_WR_Byte(0x47,OLED_CMD); 
+	OLED_WR_Byte(0xA2,OLED_CMD);//Set Display Start Line
+	OLED_WR_Byte(0x00,OLED_CMD); 
+
+  if(USE_HORIZONTAL==0)
+	{
+	 x_offset=0x10;
+	 OLED_WR_Byte(0xD3,OLED_CMD);//Set Display Offset
+	 OLED_WR_Byte(0x2C,OLED_CMD);
+	 OLED_WR_Byte(0xa0,OLED_CMD);//Set COM Output Scan Direction
+	 OLED_WR_Byte(0xC8,OLED_CMD); 
+	}
+	else
+	{
+	 x_offset=0;
+	 OLED_WR_Byte(0xD3,OLED_CMD);//Set Display Offset
+	 OLED_WR_Byte(0x74,OLED_CMD);
+	 OLED_WR_Byte(0xa1,OLED_CMD);//Set COM Output Scan Direction
+	 OLED_WR_Byte(0xC0,OLED_CMD); 
+	}
+	
+	
+	OLED_WR_Byte(0xDA,OLED_CMD);//SetSEGPinsHardwareConfiguration
+	OLED_WR_Byte(0x32,OLED_CMD);
+	
+
+	OLED_WR_Byte(0x81,OLED_CMD);//Set Contrast Control
+	OLED_WR_Byte(Contrast_level,OLED_CMD);
+
+	OLED_WR_Byte(0xD9,OLED_CMD);//SSet Pre-Charge Priod
+	OLED_WR_Byte(0x72,OLED_CMD);
+	OLED_WR_Byte(0xDB,OLED_CMD);//Set VCOMH Deselect Level 
+	OLED_WR_Byte(0x20,OLED_CMD);
+	
+	
+	OLED_WR_Byte(0xAD,OLED_CMD);//Set Internal IREF Enable
+	OLED_WR_Byte(0x00,OLED_CMD);
+	OLED_WR_Byte(0xBC,OLED_CMD);
+	OLED_WR_Byte(0x1E,OLED_CMD); 
+*/
+
+
+static const uint8_t u8x8_d_ssd1320_128x72_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, 0x47),	/* multiplex ratio 1/72 Duty  (128x72 init code) */  
+    U8X8_CA(0xa2, 0),	/* display start line (128x72 init code) */  
+
+    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 (datasheet: 0x00, but no difference with 0x10) */
+    U8X8_CA(0xbc, 0x1e), 		/* pre-charge voltage level 0x00..0x1f, reset default: 0x1e (128x72 init code)*/
+    U8X8_C(0xbf),		        	/* select linear LUT */  
+    //U8X8_DLY(1),
+  
+    U8X8_CA(0xd5, 0x11 ), 		/* Bit 0..3: clock ratio 1, 2, 4, 8, ...256, reset=0x1, Bit 4..7: F_osc 0..15 (128x72 init code)*/
+
+    U8X8_CA(0xd3, 0x2c),        /* display offset */
+    
+    U8X8_CA(0xda, 0x12),	/* Set SEG Pins Hardware Configuration:  (128x72 init code: 0x32, but 0x12 req here) */  
+    U8X8_CA(0x81, 0xDF),			/* contrast (128x72 init code)  */  
+    U8X8_CA(0xd9, 0x72),		/* Set Phase 1&2 Length, Bit 0..3: Phase 1, Bit 4..7: Phase 2, reset default 0x72 */  
+    U8X8_CA(0xdb, 0x20),		/* VCOMH Deselect Level  (128x72 init code 0x20) */  
+    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_128x72(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_128x72_display_info);
+      break;
+
+    case U8X8_MSG_DISPLAY_INIT:
+        u8x8_d_helper_display_init(u8x8);
+        u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_128x72_init_seq);
+      break;
+
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 ){
+        u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_128x72_flip0_seq);
+        u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else{
+        u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1320_128x72_flip1_seq);
+        u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+    
+    default:
+      break;
+  }
+  return 1;
+}

+ 219 - 0
components/u8g2/u8x8_d_ssd1322.c

@@ -330,6 +330,104 @@ uint8_t u8x8_d_ssd1322_nhd_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, vo
   return 1;
 }
 
+/*=========================================================*/
+/*
+https://github.com/olikraus/u8g2/issues/2386
+*/
+
+
+static const u8x8_display_info_t u8x8_ssd1322_zjy_256x64_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 20,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 100, 	/* SSD1322: 2 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* SSD1322: 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* SSD1322: 20ns, but cycle time is 100ns, so use 100/2, AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */
+  /* sck_clock_hz = */ 10000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns, increased to 8MHz (issue 215), 10 MHz (issue 301) */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 10,
+  /* write_pulse_width_ns = */ 150,	/* SSD1322: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 32,		/* 256 pixel, so we require 32 bytes for this */
+  /* tile_height = */ 8,
+  /* default_x_offset = */ 0x018,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
+  /* flipmode_x_offset = */ 0x018,
+  /* pixel_width = */ 256,
+  /* pixel_height = */ 64
+};
+
+
+static const uint8_t u8x8_d_ssd1322_zjy_256x64_init_seq[] = {
+    
+  U8X8_DLY(1),
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_DLY(1),
+  
+  U8X8_CA(0xfd, 0x12),            	/* unlock */
+  U8X8_C(0xae),		                /* display off */
+  U8X8_CA(0xb3, 0x91),			/* set display clock divide ratio/oscillator frequency (set clock as 80 frames/sec)  */  
+  U8X8_CA(0xca, 0x3f),			/* multiplex ratio 1/64 Duty (0x0F~0x3F) */  
+  U8X8_CA(0xa2, 0x00),			/* display offset, shift mapping ram counter */  
+  U8X8_CA(0xa1, 0x00),			/* display start line */  
+  //U8X8_CAA(0xa0, 0x14, 0x11),	/* Set Re-Map / Dual COM Line Mode */  
+  U8X8_CAA(0xa0, 0x16, 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_zjy_256x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ssd1322_zjy_256x64_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_zjy_256x64_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_256x64_flip1_seq);
+	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+    
+    default:
+      return u8x8_d_ssd1322_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+
+
 /*=========================================================*/
 /*
 https://github.com/olikraus/u8g2/issues/2092
@@ -427,6 +525,127 @@ uint8_t u8x8_d_ssd1322_240x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
   return 1;
 }
 
+
+
+/*=========================================================*/
+/*
+
+  Top Win OLED 240x128
+
+  Discussion: https://github.com/olikraus/u8g2/discussions/2308
+  Issue: https://github.com/olikraus/u8g2/issues/2310
+  
+  The main difference to the previous device seems to be the dual com line mode
+  (0x0a0 command)
+
+*/
+
+static const uint8_t u8x8_d_ssd1322_topwin_240x128_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CAA(0x0a0, 0x036, 0x001),		/* remap */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1322_topwin_240x128_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CAA(0x0a0, 0x024, 0x001),		/* remap */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+static const u8x8_display_info_t u8x8_ssd1322_topwin_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,		/* 240 pixel, so we require 30 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_topwin_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, 0x36, 0x001),	/* Set Re-Map / Dual COM Line Mode, https://github.com/olikraus/u8g2/discussions/2308 */  
+  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_topwin_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_topwin_240x128_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_topwin_240x128_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_topwin_240x128_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1322_topwin_240x128_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 

+ 344 - 0
components/u8g2/u8x8_d_ssd1363.c

@@ -0,0 +1,344 @@
+/*
+
+  u8x8_d_ssd1363.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.  
+
+
+  SSD1363: 
+    320 x 160 dot matrix
+    16 gray scale
+
+  https://github.com/olikraus/u8g2/issues/2490
+  
+*/
+#include "u8x8.h"
+
+
+
+
+static const uint8_t u8x8_d_ssd1363_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0af),		                /* ssd1363: display on */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1363_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x0ae),		                /* ssd1363: display off */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+
+/* interpret b as a monochrome bit pattern, write value 15 for high bit and value 0 for a low bit */
+/* topbit (msb) is sent last */
+/* example: b = 0x083 will send 0xff, 0x00, 0x00, 0xf0 */
+
+
+
+/*
+  input:
+    one tile (8 Bytes)
+  output:
+    Tile for SSD1363 (32 Bytes)
+*/
+
+static uint8_t u8x8_ssd1363_to32_dest_buf[32];
+
+static uint8_t *u8x8_ssd1363_8to32(U8X8_UNUSED u8x8_t *u8x8, uint8_t *ptr)
+{
+  uint8_t a;
+  uint8_t i;
+  uint8_t *dest;
+
+  dest = u8x8_ssd1363_to32_dest_buf;
+  
+  if ( ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0 && ptr[4] == 0 && ptr[5] == 0 && ptr[6] == 0 && ptr[7] == 0 )
+  {
+    for( i = 0; i < 32; i++ )
+      *dest++ = 0;
+    return u8x8_ssd1363_to32_dest_buf;
+  }
+  
+  a = 1;
+  for( i = 0; i < 8; i++ )
+  {
+    dest[0] = 0;
+    dest[1] = 0;
+    dest[2] = 0;
+    dest[3] = 0;
+    if ( ptr[0] & a )
+      dest[1] |= 0x0f;
+    if ( ptr[1] & a )
+      dest[1] |= 0xf0;
+    if ( ptr[2] & a )
+      dest[0] |= 0x0f;
+    if ( ptr[3] & a )
+      dest[0] |= 0xf0;
+
+    if ( ptr[4] & a )
+      dest[3] |= 0x0f;
+    if ( ptr[5] & a )
+      dest[3] |= 0xf0;
+    if ( ptr[6] & a )
+      dest[2] |= 0x0f;
+    if ( ptr[7] & a )
+      dest[2] |= 0xf0;
+    
+    a <<= 1;
+    dest += 4;
+  }  
+
+    
+  return u8x8_ssd1363_to32_dest_buf;
+}
+
+
+uint8_t u8x8_d_ssd1363_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_ssd1363_256x128_init_seq);
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_powersave1_seq);
+      break;
+#ifdef U8X8_WITH_SET_CONTRAST
+    case U8X8_MSG_DISPLAY_SET_CONTRAST:
+      u8x8_cad_StartTransfer(u8x8);
+      u8x8_cad_SendCmd(u8x8, 0x0C1 );
+      u8x8_cad_SendArg(u8x8, arg_int );	/* ssd1363 has range from 0 to 255 */
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+#endif
+    case U8X8_MSG_DISPLAY_DRAW_TILE:
+      u8x8_cad_StartTransfer(u8x8);
+      x = ((u8x8_tile_t *)arg_ptr)->x_pos;    
+      x *= 2;		// only every 4th col can be addressed
+      x += u8x8->x_offset;		
+    
+      y = (((u8x8_tile_t *)arg_ptr)->y_pos);
+      y *= 8;
+    
+      
+      u8x8_cad_SendCmd(u8x8, 0x075 );	/* set row address, moved out of the loop (issue 302) */
+      u8x8_cad_SendArg(u8x8, y);
+      u8x8_cad_SendArg(u8x8, y+7);
+      
+      do
+      {
+	c = ((u8x8_tile_t *)arg_ptr)->cnt;
+	ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+
+	do
+	{
+	  u8x8_cad_SendCmd(u8x8, 0x015 );	/* set column address */
+	  u8x8_cad_SendArg(u8x8, x );	/* start */
+	  u8x8_cad_SendArg(u8x8, x+1 );	/* end */
+
+	  u8x8_cad_SendCmd(u8x8, 0x05c );	/* write to ram */
+	  
+	  u8x8_cad_SendData(u8x8, 32, u8x8_ssd1363_8to32(u8x8, ptr));
+	  
+	  ptr += 8;
+	  x += 2;
+	  c--;
+	} while( c > 0 );
+	
+	//x += 2;
+	arg_int--;
+      } while( arg_int > 0 );
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+/*=========================================================*/
+
+static const uint8_t u8x8_d_ssd1363_256x128_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CAA(0x0a0, 0x032, 0x000),		/* remap */
+  U8X8_CA(0xa2, 0x20),			/* display offset, shift mapping ram counter */  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_ssd1363_256x128_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CAA(0x0a0, 0x020, 0x000),		/* remap */
+  U8X8_CA(0xa2, 0x80),			/* display offset, shift mapping ram counter */  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+/*=========================================================*/
+/*
+  https://github.com/olikraus/u8g2/issues/2490
+  ZJY270S0700XG21
+*/
+
+
+static const u8x8_display_info_t u8x8_ssd1363_256x128_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, 	/* ssd1363: 2 us */
+  /* post_reset_wait_ms = */ 100, /* far east OLEDs need much longer setup time */
+  /* sda_setup_time_ns = */ 50,		/* 15ns, but cycle time is 100ns, so use 100/2 */
+  /* sck_pulse_width_ns = */ 50,	/* 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), 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,	/* ssd1363: cycle time is 300ns, so use 300/2 = 150 */
+  /* tile_width = */ 32,		/* 256 pixel, so we require 32 bytes for this */
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 8,	/* this is the byte offset (there are two pixel per byte with 4 bit per pixel) */
+  /* flipmode_x_offset = */ 8,
+  /* pixel_width = */ 256,
+  /* pixel_height = */ 128
+};
+
+
+static const uint8_t u8x8_d_ssd1363_256x128_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, 0x30),			/* clock divide ratio/oscillator frequency (midas: 0x30 )  */  
+  U8X8_CA(0xca, 127),			/* multiplex ratio  (3..159) */  
+  U8X8_CA(0xa2, 0x20),			/* display offset, shift mapping ram counter */  
+
+  U8X8_CA(0xa1, 0x00),			/* display start line */  
+  
+  //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[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 ≤ 79)
+	
+	0x16 = 00010110
+*/
+  U8X8_CAA(0xa0, 0x32, 0x000),	/* Set Re-Map / Dual COM Line Mode (midas datasheet) */  
+  U8X8_CAA(0xb4, 0x32, 0x00c),	/* Display Enhancement A (midas datasheet) NOT DOCUMENTED */  
+  //U8X8_CA(0xc7, 0x0f),			/* Set Scale Factor of Segment Output Current Control */  
+  U8X8_CA(0xc1, 0xff),			/* contrast */  
+  U8X8_CA(0xba, 0x03),			/* voltage config: Vp pin is connected to cap */    
+  U8X8_C(0xb9),		                /* linear grayscale */
+  U8X8_CA(0xad, 0x90),			/* internal IREF: 0x90, external IREF: 0x80 */    
+
+  U8X8_CA(0xb1, 0x74),			/* Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment (midas) */  
+  U8X8_CA(0xbb, 0x0c),			/* precharge  voltage */    
+  
+  U8X8_CA(0xb6, 0xc8),			/* second pre charge (midas) */  
+  U8X8_CA(0xbe, 0x04),			/* vcomh (midas) */  
+  
+  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_ssd1363_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_ssd1363_256x128_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_256x128_init_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_256x128_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_ssd1363_256x128_flip1_seq);
+	u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+      }
+      break;
+    
+    default:
+      return u8x8_d_ssd1363_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+
+

+ 501 - 0
components/u8g2/u8x8_d_st7302.c

@@ -0,0 +1,501 @@
+/*
+
+  u8x8_d_st7302.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2024, 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.  
+
+
+  st7302: 
+    Ultra-Low Power Active Matrix 240 x 320
+    Mono TFT Display Driver with Controller
+  
+  https://github.com/olikraus/u8g2/issues/2436
+  
+    No Hardware Flip
+    No U8x8 Support
+
+*/
+
+
+#include "u8x8.h"
+#include <string.h>
+
+static const uint8_t u8x8_d_st7302_122x250_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x29), 				// display on
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7302_122x250_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x028),		                /* display off */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7302_122x250_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  //U8X8_CA(0x36, 0x60), 			// Memory Control 
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7302_122x250_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  //U8X8_CA(0x36, 0xa0), 			// Memory Control 
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+
+
+/*===================================================*/
+/* see also: http://www.technoblogy.com/show?3YB0 */
+
+
+#ifdef NOT_USED
+static uint8_t *u8x8_st7302_convert_60(u8x8_t *u8x8, uint8_t *p)   
+{
+  static uint8_t buf[6];
+  uint8_t bytes_per_row = u8x8->display_info->tile_width;
+  
+  
+  memset(buf, 0, 6);
+  
+  //   U8X8_CA(0x36, 0x60), 			// Memory Control 
+
+
+  // first row, left 12 pixel
+  
+  if ( p[0] & 0x80 )
+    buf[2] |= 0x02;
+  if ( p[0] & 0x40 )
+    buf[2] |= 0x08;
+  if ( p[0] & 0x20 )
+    buf[2] |= 0x20;
+  if ( p[0] & 0x10 )
+    buf[2] |= 0x80;
+
+  if ( p[0] & 0x08 )
+    buf[1] |= 0x02;
+  if ( p[0] & 0x04 )
+    buf[1] |= 0x08;
+  if ( p[0] & 0x02 )
+    buf[1] |= 0x20;
+  if ( p[0] & 0x01 )
+    buf[1] |= 0x80;
+
+  if ( p[1] & 0x80 )
+    buf[0] |= 0x02;
+  if ( p[1] & 0x40 )
+    buf[0] |= 0x08;
+  if ( p[1] & 0x20 )
+    buf[0] |= 0x20;
+  if ( p[1] & 0x10 )
+    buf[0] |= 0x80;
+
+ // first row, right 12 pixel
+   
+  if ( p[1] & 0x08 )
+    buf[5] |= 0x02;
+  if ( p[1] & 0x04 )
+    buf[5] |= 0x08;
+  if ( p[1] & 0x02 )
+    buf[5] |= 0x20;
+  if ( p[1] & 0x01 )
+    buf[5] |= 0x80;
+
+  if ( p[2] & 0x80 )
+    buf[4] |= 0x02;
+  if ( p[2] & 0x40 )
+    buf[4] |= 0x08;
+  if ( p[2] & 0x20 )
+    buf[4] |= 0x20;
+  if ( p[2] & 0x10 )
+    buf[4] |= 0x80;
+  
+  if ( p[2] & 0x08 )
+    buf[3] |= 0x02;
+  if ( p[2] & 0x04 )
+    buf[3] |= 0x08;
+  if ( p[2] & 0x02 )
+    buf[3] |= 0x20;
+  if ( p[2] & 0x01 )
+    buf[3] |= 0x80;
+  
+  p += u8x8->display_info->tile_width;
+
+  // second row, left 12 pixel
+  
+  if ( p[0] & 0x80 )
+    buf[2] |= 0x01;
+  if ( p[0] & 0x40 )
+    buf[2] |= 0x04;
+  if ( p[0] & 0x20 )
+    buf[2] |= 0x10;
+  if ( p[0] & 0x10 )
+    buf[2] |= 0x40;
+
+  if ( p[0] & 0x08 )
+    buf[1] |= 0x01;
+  if ( p[0] & 0x04 )
+    buf[1] |= 0x04;
+  if ( p[0] & 0x02 )
+    buf[1] |= 0x10;
+  if ( p[0] & 0x01 )
+    buf[1] |= 0x40;
+
+  if ( p[1] & 0x80 )
+    buf[0] |= 0x01;
+  if ( p[1] & 0x40 )
+    buf[0] |= 0x04;
+  if ( p[1] & 0x20 )
+    buf[0] |= 0x10;
+  if ( p[1] & 0x10 )
+    buf[0] |= 0x40;
+
+ // second row, right 12 pixel
+   
+  if ( p[1] & 0x08 )
+    buf[5] |= 0x01;
+  if ( p[1] & 0x04 )
+    buf[5] |= 0x04;
+  if ( p[1] & 0x02 )
+    buf[5] |= 0x10;
+  if ( p[1] & 0x01 )
+    buf[5] |= 0x40;
+
+  if ( p[2] & 0x80 )
+    buf[4] |= 0x01;
+  if ( p[2] & 0x40 )
+    buf[4] |= 0x04;
+  if ( p[2] & 0x20 )
+    buf[4] |= 0x10;
+  if ( p[2] & 0x10 )
+    buf[4] |= 0x40;
+  
+  if ( p[2] & 0x08 )
+    buf[3] |= 0x01;
+  if ( p[2] & 0x04 )
+    buf[3] |= 0x04;
+  if ( p[2] & 0x02 )
+    buf[3] |= 0x10;
+  if ( p[2] & 0x01 )
+    buf[3] |= 0x40;
+  
+  return buf;
+}
+#endif
+
+static uint8_t *u8x8_st7302_convert_a0(u8x8_t *u8x8, uint8_t *p)   
+{
+  static uint8_t buf[6];
+  static uint8_t map1[16] = {
+      /* 0x00 0000 */ 0,
+      /* 0x01 0001 */0x01,
+      /* 0x02 0010 */0x04,
+      /* 0x03 0011 */0x04+0x01,
+      /* 0x04 0100 */0x10,
+      /* 0x05 0101 */0x10+0x01,
+      /* 0x06 0110 */0x10+0x04,
+      /* 0x07 0111 */0x10+0x04+0x01,
+      /* 0x08 1000 */ 0x40,
+      /* 0x09 1001 */ 0x40+0x01,
+      /* 0x0a 1010 */ 0x40+0x04,
+      /* 0x0b 1011 */ 0x40+0x04+0x01,
+      /* 0x0c 1100 */ 0x40+0x10,
+      /* 0x0d 1101 */ 0x40+0x10+0x01,
+      /* 0x0e 1110 */ 0x40+0x10+0x04,
+      /* 0x0f 1111 */  0x40+0x10+0x04+0x01
+  };
+  static uint8_t map2[16] = {
+      /* 0x00 0000 */ 0,
+      /* 0x01 0001 */0x02,
+      /* 0x02 0010 */0x08,
+      /* 0x03 0011 */0x08+0x02,
+      /* 0x04 0100 */0x20,
+      /* 0x05 0101 */0x20+0x02,
+      /* 0x06 0110 */0x20+0x08,
+      /* 0x07 0111 */0x20+0x08+0x02,
+      /* 0x08 1000 */ 0x80,
+      /* 0x09 1001 */ 0x80+0x02,
+      /* 0x0a 1010 */ 0x80+0x08,
+      /* 0x0b 1011 */ 0x80+0x08+0x02,
+      /* 0x0c 1100 */ 0x80+0x20,
+      /* 0x0d 1101 */ 0x80+0x20+0x02,
+      /* 0x0e 1110 */ 0x80+0x20+0x08,
+      /* 0x0f 1111 */  0x80+0x20+0x08+0x02
+  };
+  
+  
+  memset(buf, 0, 6);
+  
+  //   U8X8_CA(0x36, 0x0), 			// Memory Control 
+
+
+  // first row, left 12 pixel
+
+  buf[0] |= map1[p[0]>>4];
+  buf[1] |= map1[p[0] & 0x0f];
+  buf[2] |= map1[p[1]>>4];
+
+ // first row, right 12 pixel
+   
+  buf[3] |= map1[p[1] & 0x0f];
+  buf[4] |= map1[p[2]>>4];
+  buf[5] |= map1[p[2] & 0x0f];
+  
+  p += u8x8->display_info->tile_width;
+
+  // second row, left 12 pixel
+
+  buf[0] |= map2[p[0]>>4];
+  buf[1] |= map2[p[0] & 0x0f];
+  buf[2] |= map2[p[1]>>4];
+  
+ // second row, right 12 pixel
+
+  buf[3] |= map2[p[1] & 0x0f];
+  buf[4] |= map2[p[2]>>4];
+  buf[5] |= map2[p[2] & 0x0f];
+  return buf;
+}
+
+
+
+
+/*===================================================*/
+/* 
+  see also:
+  https://github.com/zhcong/ST7302-for-arduino/blob/c9390fabcacefe7c36a113cd3e62959418c13b97/libraries/ST7302SPI/ST7302SPI.cpp#L21
+*/
+static const uint8_t u8x8_d_st7302_122x250_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_C(0x01),                                 // software reset
+  U8X8_DLY(100),
+  U8X8_C(0x28), 				// display off
+  U8X8_CAA(0xC7, 0x26, 0xE9), 			// disable OSC
+  U8X8_CA(0xD1, 0x00), 			// Booster disable
+  U8X8_DLY(20),
+  U8X8_C(0x10),                                 // sleep in: enter sleep mode
+  U8X8_DLY(20),
+  U8X8_C(0x01),                                 // software reset
+  U8X8_DLY(20),                                 // wait
+  U8X8_C(0x38), 				// High Power Mode
+  U8X8_CA(0xEB, 0x02), 			// Disable NVM Load
+  U8X8_CA(0xD7, 0x68), 			// NVM Load Control: Enable ID1 ID2 ID3 Load
+  U8X8_CA(0xD1, 0x01), 			// Booster Enable
+  U8X8_CA(0xC0, 0x80), 			// Gate Voltage Setting VGH=12V (upper 4 bit, 8V-15V); VGL=-5V (lower 4 bit, -5V .. -10V)
+  U8X8_C(0x0C1),                                // Source Voltage Control 1
+  U8X8_A6(0x28,0x28,0x28,0x28,0x14,0x00),       // Source high voltage in reflective and transmissive mode, gamma voltage 1&2 
+  U8X8_C(0x0C2),                                // Source Voltage Control 1
+  U8X8_A4(0x00,0x00,0x00,0x00),       // Source low voltage in reflective and transmissive mode 
+  U8X8_CA(0xCB, 0x14), 			// VCOMH: 0x14 = 4V (0x28 = 5V)
+  U8X8_CAA(0xB4, 0xE5, 0x77), 			// Update Period Gate EQ Control, why 0x77??? it should be 0x66 according to the datasheet
+  U8X8_A8(0xF1, 0xFF, 0xFF, 0x4F, 0xF1, 0xFF, 0xFF, 0X4F),
+  U8X8_CA(0xB0, 0x64), 			// Duty Cycle... this must be before sleep out
+  U8X8_C(0x11),                                 // sleep out: furn off sleep mode
+  U8X8_DLY(120),
+  U8X8_CAA(0xC7, 0xA6, 0xE9), 			// Enable OSC
+  U8X8_CA(0x36, 0xa0), 			// Memory Control 
+  
+  U8X8_CA(0x3A, 0x11), 			// Data Format 
+  U8X8_CA(0xB9, 0x23), 			// Source Setting: Clear RAM off 
+  U8X8_CA(0xB8, 0x09), 			// Panel Setting / Panel Layout 
+  U8X8_CAA(0x2A, 0x05, 0x36), 			// col addr
+  U8X8_CAA(0x2B, 0x00, 0xC7), 			// row addr
+  U8X8_CA(0xD0, 0x1F), 			// Not in datasheet
+  U8X8_C(0x29), 				// display on
+  U8X8_CA(0x72, 0x00), 			// Not in datasheet
+  U8X8_CAA(0xB2,1, 5),                  // Frame Rate for High and Low Power Mode (hier: 32Hz and 8Hz) 
+  U8X8_C(0x39), 				// enable Low Power Mode...: 8Hz, see above
+  U8X8_DLY(100),
+
+  /*
+  U8X8_CAA(0x2A, 0x19, 0x3a), 			// col addr  0x14 < col < 0x3b
+  U8X8_CAA(0x2B, 115, 115), 			// row addr (0..250, y in u8g2), 0 is top row in u8g2
+  U8X8_C(0x2C), 			// write start
+  U8X8_D1(0xff), 			// pixel data
+  U8X8_D1(0xff), 			// pixel data
+  U8X8_D1(0xff), 			// pixel data
+  
+  U8X8_D1(0xff), 			// pixel data
+  U8X8_D1(0xff), 			// pixel data
+  U8X8_D1(0xff), 			// pixel data
+
+  U8X8_D1(0xff), 			// pixel data
+  U8X8_D1(0xff), 			// pixel data
+  U8X8_D1(0xff), 			// pixel data
+  
+  U8X8_D1(0xff), 			// pixel data
+  U8X8_D1(0xff), 			// pixel data
+  U8X8_D1(0xff), 			// pixel data
+
+  U8X8_CAA(0x2A, 0x19, 0x3a), 			// col addr  0x14 < col < 0x3b
+  U8X8_CAA(0x2B, 116, 116), 			// row addr (0..250, y in u8g2), 0 is top row in u8g2
+  U8X8_C(0x2C), 			// write start
+  U8X8_D1(0x80), 			// pixel data
+  U8X8_D1(0x00), 			// pixel data
+  U8X8_D1(0x00), 			// pixel data
+  
+  U8X8_D1(0x00), 			// pixel data
+  U8X8_D1(0x00), 			// pixel data
+  U8X8_D1(0x00), 			// pixel data
+
+  U8X8_D1(0x00), 			// pixel data
+  U8X8_D1(0x00), 			// pixel data
+  U8X8_D1(0x00), 			// pixel data
+  
+  U8X8_D1(0x00), 			// pixel data
+  U8X8_D1(0x00), 			// pixel data
+  U8X8_D1(0x00), 			// pixel data
+  */
+
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()           			/* end of sequence */
+};
+
+
+
+
+static const u8x8_display_info_t u8x8_st7302_122x250_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 = */ 3, 	
+  /* post_reset_wait_ms = */ 3, 		/**/
+  /* sda_setup_time_ns = */ 10,		/* */
+  /* sck_pulse_width_ns = */ 30,	/*  */
+  /* 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,	/* 400KHz */
+  /* data_setup_time_ns = */ 15,
+  /* write_pulse_width_ns = */ 70,	
+  /* tile_width = */ 16,
+  /* tile_height = */ 32,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 122,
+  /* pixel_height = */ 250
+};
+
+uint8_t u8x8_d_st7302_122x250(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  uint16_t x;
+  uint8_t c, i, y;
+  uint8_t *ptr;
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7302_122x250_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7302_122x250_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7302_122x250_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7302_122x250_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7302_122x250_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7302_122x250_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 );	
+      u8x8_cad_SendArg(u8x8, arg_int>>6 );	
+      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*=4;
+    
+      y+=115;           // specific for the 122x250 LCD
+
+      u8x8_cad_StartTransfer(u8x8);
+
+      for( i = 0; i < 4; i++ )
+      {
+        
+        u8x8_cad_SendCmd(u8x8, 0x2a);
+        u8x8_cad_SendArg(u8x8, 0x19);   // specific for the 122x250 LCD
+        u8x8_cad_SendArg(u8x8, 0x3a );
+      
+        u8x8_cad_SendCmd(u8x8, 0x2b ); 
+        u8x8_cad_SendArg(u8x8, y+i); 
+        u8x8_cad_SendArg(u8x8, y+i); 
+        u8x8_cad_SendCmd(u8x8, 0x02c );		// write data 
+      
+        c = ((u8x8_tile_t *)arg_ptr)->cnt;
+        ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+        
+        ptr += u8x8->display_info->tile_width*i*2;
+        
+        c = (c+2)/3;          // calculate the number of 24 bit blocks to send
+        
+        
+        while( c > 0 )
+        {
+          u8x8_cad_SendData(u8x8, 6, u8x8_st7302_convert_a0(u8x8, ptr)); 	
+          ptr+=3;
+          --c;
+        }
+      }
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}

+ 694 - 0
components/u8g2/u8x8_d_st7305.c

@@ -0,0 +1,694 @@
+/*
+
+  u8x8_d_st7305.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2025, 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.  
+
+
+  st7305: 240 x 320             122x250
+  st7305: 264 x 320             168x384, 200x200
+    Mono TFT Display Driver with Controller
+    
+  st7305 seems to be almost compatible to the st7303, however they have a different memory architecture
+  
+  https://github.com/olikraus/u8g2/issues/2436
+  
+    No Hardware Flip
+    No U8x8 Support
+
+*/
+
+
+#include "u8x8.h"
+#include <string.h>
+
+static const uint8_t u8x8_d_st7305_122x250_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x29), 				// display on
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7305_122x250_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x028),		                /* display off */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7305_122x250_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  //U8X8_CA(0x36, 0x60), 			// Memory Control 
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7305_122x250_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  //U8X8_CA(0x36, 0xa0), 			// Memory Control 
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+
+
+/*===================================================*/
+/* see also: http://www.technoblogy.com/show?3YB0 */
+
+
+static uint8_t *u8x8_st7305_convert_a0(u8x8_t *u8x8, uint8_t *p)   
+{
+  static uint8_t buf[6];
+  
+#ifdef NOT_WORKING
+  /* u8g2 first row */
+  static uint8_t map1[16] = {
+      /* 0x00 0000 */ 0,
+      /* 0x01 0001 */0x04,
+      /* 0x02 0010 */0x01,
+      /* 0x03 0011 */0x04+0x01,
+      /* 0x04 0100 */0x40,
+      /* 0x05 0101 */0x40+0x04,
+      /* 0x06 0110 */0x40+0x01,
+      /* 0x07 0111 */0x40+0x04+0x01,
+      /* 0x08 1000 */ 0x10,
+      /* 0x09 1001 */ 0x10+0x04,
+      /* 0x0a 1010 */ 0x10+0x01,
+      /* 0x0b 1011 */ 0x10+0x04+0x01,
+      /* 0x0c 1100 */ 0x40+0x10,
+      /* 0x0d 1101 */ 0x40+0x10+0x04,
+      /* 0x0e 1110 */ 0x40+0x10+0x01,
+      /* 0x0f 1111 */  0x40+0x10+0x04+0x01
+  };
+  /* u8g2 second row */
+  static uint8_t map2[16] = {
+      /* 0x00 0000 */ 0,
+      /* 0x01 0001 */0x08,
+      /* 0x02 0010 */0x02,
+      /* 0x03 0011 */0x08+0x02,
+      /* 0x04 0100 */0x80,
+      /* 0x05 0101 */0x80+0x08,
+      /* 0x06 0110 */0x80+0x02,
+      /* 0x07 0111 */0x80+0x08+0x02,
+      /* 0x08 1000 */ 0x20,
+      /* 0x09 1001 */ 0x20+0x08,
+      /* 0x0a 1010 */ 0x20+0x02,
+      /* 0x0b 1011 */ 0x20+0x08+0x02,
+      /* 0x0c 1100 */ 0x80+0x20,
+      /* 0x0d 1101 */ 0x80+0x20+0x08,
+      /* 0x0e 1110 */ 0x80+0x20+0x02,
+      /* 0x0f 1111 */  0x80+0x20+0x08+0x02
+  };
+  #endif
+
+ /* contributed by https://github.com/ischenz */
+ /* u8g2 first row */ 
+  static uint8_t map1[16] = { 
+      0x00, 0x02, 0x08, 0x0A, 
+      0x20, 0x22, 0x28, 0x2A, 
+      0x80, 0x82, 0x88, 0x8A, 
+      0xA0, 0xA2, 0xA8, 0xAA }; 
+ /* u8g2 second row */ 
+  static uint8_t map2[16] = { 
+    0x00, 0x01, 0x04, 0x05, 
+    0x10, 0x11, 0x14, 0x15, 
+    0x40, 0x41, 0x44, 0x45, 
+    0x50, 0x51, 0x54, 0x55 };  
+  
+  memset(buf, 0, 6);
+  
+
+  // first row, left 12 pixel out of 24 pixel (=3 bytes)
+
+  buf[0] |= map1[p[0]>>4];
+  buf[1] |= map1[p[0] & 0x0f];
+  buf[2] |= map1[p[1]>>4];
+
+ // first row, right 12 pixel
+   
+  buf[3] |= map1[p[1] & 0x0f];
+  buf[4] |= map1[p[2]>>4];
+  buf[5] |= map1[p[2] & 0x0f];
+  
+  p += u8x8->display_info->tile_width;
+
+  // second row, left 12 pixel
+
+  buf[0] |= map2[p[0]>>4];
+  buf[1] |= map2[p[0] & 0x0f];
+  buf[2] |= map2[p[1]>>4];
+  
+ // second row, right 12 pixel
+
+  buf[3] |= map2[p[1] & 0x0f];
+  buf[4] |= map2[p[2]>>4];
+  buf[5] |= map2[p[2] & 0x0f];
+  return buf;
+}
+
+
+
+
+/*===================================================*/
+/* 
+  see also:
+  https://github.com/zhcong/st7302-for-arduino/blob/c9390fabcacefe7c36a113cd3e62959418c13b97/libraries/st7305SPI/st7305SPI.cpp#L21
+*/
+static const uint8_t u8x8_d_st7305_122x250_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_C(0x01),                                 // software resets
+  U8X8_DLY(100),
+  U8X8_C(0x28), 				// display off
+  U8X8_CAA(0xC7, 0x26, 0xE9), 			// disable OSC
+  U8X8_CA(0xD1, 0x00), 			// Booster disable
+  U8X8_DLY(20),
+  U8X8_C(0x10),                                 // sleep in: enter sleep mode
+  U8X8_DLY(20),
+  U8X8_C(0x01),                                 // software reset
+  U8X8_DLY(20),                                 // wait
+  //U8X8_C(0x38), 				// High Power Mode
+  //U8X8_CA(0xEB, 0x02), 			// Disable NVM Load
+  //U8X8_CA(0xD7, 0x68), 			// NVM Load Control: Enable ID1 ID2 ID3 Load
+  //U8X8_CA(0xD1, 0x01), 			// Booster Enable
+  //U8X8_CA(0xC0, 0x80), 			// Gate Voltage Setting VGH=12V (upper 4 bit, 8V-15V); VGL=-5V (lower 4 bit, -5V .. -10V)
+  U8X8_CAA(0xD6, 0x17, 0x02),
+  U8X8_CA(0xD1, 0x01), 
+  U8X8_CAA(0xC0, 0x12, 0x0a),//chen.x
+  U8X8_C(0x0C1),                                // Source Voltage Control 1
+  U8X8_A4(115,0x3E,0x3C,0x3C), 
+  U8X8_C(0x0C2),                                // Source Voltage Control 1
+  U8X8_A4(0,0x21,0x23,0x23),       // Source low voltage in reflective and transmissive mode 
+  U8X8_C(0x0C4),    //ischen.x
+  U8X8_A4(50,0x5C,0x5A,0x5A), 
+  U8X8_C(0x0C5),    //ischen.x
+  U8X8_A4(50,0x35,0x37,0x37),
+  U8X8_CAA(0xD8, 0x80, 0xE9),
+  
+  //U8X8_CA(0xCB, 0x14), 			// VCOMH: 0x14 = 4V (0x28 = 5V)
+  U8X8_CA(0xB2, 0x12),
+  U8X8_CAA(0xB3, 0xE5, 0xF6), 			// Update Period Gate EQ Control, why 0x77??? it should be 0x66 according to the datasheet
+  U8X8_A8(0x17, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x71),
+  U8X8_CAA(0xB4, 0x05, 0x46), 			// Update Period Gate EQ Control, why 0x77??? it should be 0x66 according to the datasheet
+  U8X8_A6(0x77, 0x77, 0x77, 0x77, 0x76, 0x45),
+  U8X8_CAAA(0x62, 0x32, 0x03, 0x1f),                                
+  U8X8_CA(0xB7, 0x13),
+  U8X8_CA(0xB0, 0x32), 			// Duty Cycle... this must be before sleep out, 200x200 display: 0x64 --> 0x32
+  
+  U8X8_C(0x11),                                 // sleep out: furn off sleep mode
+  U8X8_DLY(120),
+  U8X8_CA(0xC9, 0x00),
+  U8X8_CA(0x36, 0xa4), 			// Memory Control, 0xa4 for the 200x200 display
+  
+  U8X8_CA(0x3A, 0x11), 			// Data Format 
+  U8X8_CA(0xB9, 0x20), 			// Source Setting: Clear RAM off *******<-----
+  U8X8_CA(0xB8, 0x29), 			// Panel Setting / Panel Layout 
+  U8X8_CAA(0x2A, 0x16, 0x27), 			// col addr
+  U8X8_CAA(0x2B, 0x00, 0x63), 			// row addr
+  U8X8_CA(0x35, 0x00),
+  U8X8_CA(0xD0, 0xFF), 			// Not in datasheet
+  //U8X8_CA(0x72, 0x00), 			// Not in datasheet
+  //U8X8_CAA(0xB2,1, 5),                  // Frame Rate for High and Low Power Mode (hier: 32Hz and 8Hz) 
+  U8X8_C(0x38), 				// enable Low Power Mode...: 8Hz, see above
+  U8X8_C(0x29), 				// display on
+  U8X8_C(0x20),
+  U8X8_CA(0xBB, 0x4F),
+  U8X8_DLY(100),
+ 
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()           			/* end of sequence */
+};
+
+
+
+static const u8x8_display_info_t u8x8_st7305_122x250_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 = */ 3, 	
+  /* post_reset_wait_ms = */ 3, 		/**/
+  /* sda_setup_time_ns = */ 10,		/* */
+  /* sck_pulse_width_ns = */ 30,	/*  */
+  /* 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,	/* 400KHz */
+  /* data_setup_time_ns = */ 15,
+  /* write_pulse_width_ns = */ 70,	
+  /* tile_width = */ 16,
+  /* tile_height = */ 32,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 122,
+  /* pixel_height = */ 250
+};
+
+uint8_t u8x8_d_st7305_122x250(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  uint16_t x;
+  uint8_t c, i, y;
+  uint8_t *ptr;
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7305_122x250_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_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 );	
+      u8x8_cad_SendArg(u8x8, arg_int>>6 );	
+      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*=4;
+    
+      y+=115;           // specific for the 122x250 LCD
+
+      u8x8_cad_StartTransfer(u8x8);
+
+      for( i = 0; i < 4; i++ )
+      {
+        
+        u8x8_cad_SendCmd(u8x8, 0x2a);
+        u8x8_cad_SendArg(u8x8, 0x19);   // specific for the 122x250 LCD
+        u8x8_cad_SendArg(u8x8, 0x3a );
+      
+        u8x8_cad_SendCmd(u8x8, 0x2b ); 
+        u8x8_cad_SendArg(u8x8, y+i); 
+        u8x8_cad_SendArg(u8x8, y+i); 
+        u8x8_cad_SendCmd(u8x8, 0x02c );		// write data 
+      
+        c = ((u8x8_tile_t *)arg_ptr)->cnt;
+        ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+        
+        ptr += u8x8->display_info->tile_width*i*2;
+        
+        c = (c+2)/3;          // calculate the number of 24 bit blocks to send
+        
+        
+        while( c > 0 )
+        {
+          u8x8_cad_SendData(u8x8, 6, u8x8_st7305_convert_a0(u8x8, ptr)); 	
+          ptr+=3;
+          --c;
+        }
+      }
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+/*=====================================================================*/
+/* 200x200, https://admin.osptek.com/uploads/YDP_154_H008_V3_c24b455ff9.pdf */
+
+
+static const u8x8_display_info_t u8x8_st7305_200x200_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 = */ 3, 	
+  /* post_reset_wait_ms = */ 3, 		/**/
+  /* sda_setup_time_ns = */ 10,		/* */
+  /* sck_pulse_width_ns = */ 30,	/*  */
+  /* 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,	/* 400KHz */
+  /* data_setup_time_ns = */ 15,
+  /* write_pulse_width_ns = */ 70,	
+  /* tile_width = */ 26,   /* tile width is 26*8=208, because this display requires 12 bit blocks, which would be 204 pixel, so next tile is at 208 */
+  /* tile_height = */ 25,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 200,              /* not 100% sure, whether this works with the tile_width of 26... */
+  /* pixel_height = */ 200
+};
+
+uint8_t u8x8_d_st7305_200x200(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  uint16_t x;
+  uint8_t c, i, y;
+  uint8_t *ptr;
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7305_200x200_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_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 );	
+      u8x8_cad_SendArg(u8x8, arg_int>>6 );	
+      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*=4;
+    
+      y+=0;           // 200x200 display
+
+      u8x8_cad_StartTransfer(u8x8);
+
+      for( i = 0; i < 4; i++ )
+      {
+        
+        u8x8_cad_SendCmd(u8x8, 0x2a);   // column address set
+        u8x8_cad_SendArg(u8x8, 0x16);   // 0x019 for the 122x250 LCD --> 0x016 for the 200x200 display
+        u8x8_cad_SendArg(u8x8, 0x27 );  // 204 pixel for the 200x200 display
+      
+        u8x8_cad_SendCmd(u8x8, 0x2b ); 
+        u8x8_cad_SendArg(u8x8, y+i); 
+        u8x8_cad_SendArg(u8x8, y+i); 
+        u8x8_cad_SendCmd(u8x8, 0x02c );		// write data 
+      
+        c = ((u8x8_tile_t *)arg_ptr)->cnt;
+        ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+        
+        ptr += u8x8->display_info->tile_width*i*2;
+        
+        c = (c+2)/3;          // calculate the number of 24 bit blocks to send
+        
+        
+        while( c > 0 )
+        {
+          u8x8_cad_SendData(u8x8, 6, u8x8_st7305_convert_a0(u8x8, ptr)); 	
+          ptr+=3;
+          --c;
+        }
+      }
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+
+/*=====================================================================*/
+/* 168x384, https://github.com/olikraus/u8g2/issues/2661 */
+
+
+#ifdef NOT_USED
+static const uint8_t u8x8_d_st7305_168x384_powersave0_seq[] = {
+    U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
+    U8X8_C(0x29),          // display on
+    U8X8_END_TRANSFER(),   /* disable chip */
+    U8X8_END()             /* end of sequence */
+};
+
+
+static const uint8_t u8x8_d_st7305_168x384_powersave1_seq[] = {
+    U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
+    U8X8_C(0x028),         /* display off */
+    U8X8_END_TRANSFER(),   /* disable chip */
+    U8X8_END()             /* end of sequence */
+};
+
+
+static const uint8_t u8x8_d_st7305_168x384_flip0_seq[] = {
+    U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */
+    // U8X8_CA(0x36, 0x60), 			// Memory Control
+    U8X8_END_TRANSFER(), /* disable chip */
+    U8X8_END()           /* end of sequence */
+};
+#endif
+
+
+static const uint8_t u8x8_d_st7305_168x384_init_seq[] = {
+    U8X8_START_TRANSFER(),
+
+
+    /* Software Reset */
+    U8X8_C(0x01),
+    U8X8_DLY(100),
+
+
+    /* Settings */
+    // 以下在芯片手册基础上,按照显示屏厂家给的示例代码调整
+    U8X8_CAA(0xD6, 0x13, 0x02), // NVM Load Control
+    U8X8_CA(0xD1, 0x01),        // Booster Enable
+    U8X8_CAA(0xC0, 0x12, 0x0A), // Gate Voltage Setting: VGH=15V, VGL=-10V
+
+
+    U8X8_CAAAA(0xC1, 0x3C, 0x3E, 0x3C, 0x3C), // VSHP Setting: VSHP1~4 = 4.8V
+    U8X8_CAAAA(0xC2, 0x23, 0x21, 0x23, 0x23), // VSLP Setting: VSHP1~4 = 0.98V
+    U8X8_CAAAA(0xC4, 0x5A, 0x5C, 0x5A, 0x5A), // VSHN Setting: VSHP1~4 = -3.6V
+    U8X8_CAAAA(0xC5, 0x37, 0x35, 0x37, 0x37), // VSLN Setting: VSHP1~4 = 0.22V
+
+
+    U8X8_CAA(0xD8, 0xA6, 0xE9), // OSC Setting
+    U8X8_CA(0xB2, 0x12),        // Frame Rate Control: HPM=32Hz, LPM=1Hz
+
+
+    U8X8_CAAAA(0xB3, 0xE5, 0xF6, 0x17, 0x77), // Update Period Gate EQ Control in HPM
+    U8X8_A6(0x77, 0x77, 0x77, 0x77, 0x77, 0x71),
+
+
+    U8X8_CAA(0xB4, 0x05, 0x46), // Update Period Gate EQ Control in LPM
+    U8X8_A6(0x77, 0x77, 0x77, 0x77, 0x76, 0x45),
+
+
+    U8X8_CAAA(0x62, 0x32, 0x03, 0x1F), // Gate Timing Control
+    U8X8_CA(0xB7, 0x13),               // Source EQ Enable
+    U8X8_CA(0xB0, 0x60),               // Gate Line Setting: 384 line
+
+
+    U8X8_C(0x11), // Sleep Out
+    U8X8_DLY(10),
+
+
+    U8X8_CA(0xC9, 0x00), // Source Voltage Select: VSHP1; VSLP1 ; VSHN1 ; VSLN1
+    U8X8_CA(0x36, 0x48), // Memory Data Access Control
+    U8X8_CA(0x3A, 0x11), // Data Format Select
+    U8X8_CA(0xB9, 0x20), // Gamma Mode Setting: Mono 00:4GS
+    U8X8_CA(0xB8, 0x29), // Panel Setting, 1-Dot inversion, Frame inversion, One Line Interlace
+
+
+    U8X8_CAA(0x2A, 0x17, 0x24), // Column Address Setting: 0X24-0X16=14, 14*12=168
+    U8X8_CAA(0x2B, 0x00, 0xBF), // Row Address Setting: 192*2=384
+    U8X8_CA(0x35, 0x00),        // TE Setting
+    U8X8_CA(0xD0, 0xFF),        // Enable Auto Power down
+    U8X8_C(0x38),               // High Power Mode ON
+    // U8X8_C(0x39),               // Low Power Mode ON
+
+
+    /* Display ON */
+    U8X8_C(0x29),        // Display ON
+    U8X8_C(0x20),        // Display Inversion Off
+    U8X8_CA(0xBB, 0x4F), // Enable Clear RAM to 0
+
+
+    U8X8_END_TRANSFER(),
+    U8X8_END()
+
+
+};
+
+
+static const u8x8_display_info_t u8x8_st7305_168x384_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 = */ 3,
+        /* post_reset_wait_ms = */ 3,   /**/
+        /* sda_setup_time_ns = */ 10,   /* */
+        /* sck_pulse_width_ns = */ 30,  /*  */
+        /* 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, /* 400KHz */
+        /* data_setup_time_ns = */ 15,
+        /* write_pulse_width_ns = */ 70,
+        /* tile_width = */ 21, /* tile width is 21*8=168, because this display requires 12 bit blocks, which would be 168 pixel, so next tile is at 168 */
+        /* tile_height = */ 48,
+        /* default_x_offset = */ 0,
+        /* flipmode_x_offset = */ 0,
+        /* pixel_width = */ 168, /* not 100% sure, whether this works with the tile_width of 21... */
+        /* pixel_height = */ 384};
+
+
+uint8_t u8x8_d_st7305_168x384(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  uint16_t x;
+  uint8_t c, i, y;
+  uint8_t *ptr;
+  switch(msg)
+  {
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_168x384_init_seq);    
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7305_168x384_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_powersave0_seq);
+      else
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_powersave1_seq);
+      break;
+    case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+      if ( arg_int == 0 )
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_flip0_seq);
+	u8x8->x_offset = u8x8->display_info->default_x_offset;
+      }
+      else
+      {
+	u8x8_cad_SendSequence(u8x8, u8x8_d_st7305_122x250_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 );	
+      u8x8_cad_SendArg(u8x8, arg_int>>6 );	
+      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*=4;
+    
+      y+=0;         // specific for the 168x384 LCD
+
+
+      u8x8_cad_StartTransfer(u8x8);
+
+
+      for( i = 0; i < 4; i++ )
+      {
+        
+        u8x8_cad_SendCmd(u8x8, 0x2a);   // column address set
+        u8x8_cad_SendArg(u8x8, 0x17);   // 0x019 for the 122x250 LCD --> 0x016 for the 200x200 display
+        u8x8_cad_SendArg(u8x8, 0x24);  // 204 pixel for the 200x200 display
+      
+        u8x8_cad_SendCmd(u8x8, 0x2b); 
+        u8x8_cad_SendArg(u8x8, y+i); 
+        u8x8_cad_SendArg(u8x8, y+i); 
+        u8x8_cad_SendCmd(u8x8, 0x2c);		// write data 
+      
+        c = ((u8x8_tile_t *)arg_ptr)->cnt;
+        ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+        
+        ptr += u8x8->display_info->tile_width*i*2;
+        
+        c = (c+2)/3;          // calculate the number of 24 bit blocks to send
+        
+        
+        while( c > 0 )
+        {
+          u8x8_cad_SendData(u8x8, 6, u8x8_st7305_convert_a0(u8x8, ptr)); 	
+          ptr+=3;
+          --c;
+        }
+      }
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}

+ 428 - 0
components/u8g2/u8x8_d_st75161.c

@@ -0,0 +1,428 @@
+/*
+
+  u8x8_d_st75161.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2024, olikraus@gmail.com
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without modification, 
+  are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this list 
+    of conditions and the following disclaimer.
+    
+  * Redistributions in binary form must reproduce the above copyright notice, this 
+    list of conditions and the following disclaimer in the documentation and/or other 
+    materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
+
+  https://github.com/olikraus/u8g2/issues/2481
+
+
+  0x030	ext 00
+  0x031	ext 01
+  0x038	ext 10
+  0x039	ext 11
+  
+  cad 011
+  
+  
+  normal mode:
+	0x00c	bit format
+  U8X8_CA( 0xbc, 0x00 ),	data scan dir 
+  U8X8_A( 0xa6 ),				
+  y: 0 offset
+  
+  flip mode:
+	0x008	bit format
+  U8X8_CA( 0xbc, 0x03 ),	data scan dir 
+  U8X8_A( 0xa6 ),				
+  y: 5 offset
+	
+  
+*/
+
+
+#include "u8x8.h"
+
+
+/* not a real power down for the st75256... just a display off */
+static const uint8_t u8x8_d_st75256_256x128_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C( 0x030 ),				/* select 00 commands */  
+  U8X8_C( 0x94 ),				/* sleep out */
+  U8X8_DLY(10),
+  U8X8_C( 0xaf ),				/* display on */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st75256_256x128_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_C( 0xae ),				/* display off */
+  U8X8_C( 0x95 ),				/* sleep in */
+  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_st75161_jlx160160_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_CA( 0x0AB, 0 ),				/* start line */
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_st75161_jlx160160_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_CA( 0x0AB, 0 ),				/* start line */
+  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 ),				/* ??? */
+
+  //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_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
+
+
+/*=============================================*/
+/* jlx160160  https://github.com/olikraus/u8g2/issues/1642 */
+
+static const u8x8_display_info_t u8x8_st75161_jlx160160_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 = */ 20,
+  /* default_x_offset = */ 0,	/*  y (!) offset in flipmode 0 */
+  /* flipmode_x_offset = */ 1,		/* y (!) offset in flipmode 0 */
+  /* pixel_width = */ 160,
+  /* pixel_height = */ 160
+};
+
+
+/*
+from the JLX160160 datasheet:
+
+transfer_command_lcd(0x30);//EXT=0
+transfer_command_lcd(0x94);//Sleep out
+transfer_command_lcd(0x31);//EXT=1
+transfer_command_lcd(0xD7);//Autoread disable
+transfer_data_lcd(0X9F);//
+transfer_command_lcd(0x32);//Analog SET
+transfer_data_lcd(0x00);//OSC Frequency adjustment
+transfer_data_lcd(0x01);//Frequency on booster capacitors->6KHz
+transfer_data_lcd(0x00);//Bias=1/14
+transfer_command_lcd(0x20);// Gray Level
+transfer_data_lcd(0x01);
+transfer_data_lcd(0x03);
+transfer_data_lcd(0x05);
+transfer_data_lcd(0x07);
+transfer_data_lcd(0x09);
+transfer_data_lcd(0x0b);
+transfer_data_lcd(0x0d);
+transfer_data_lcd(0x10);
+transfer_data_lcd(0x11);
+transfer_data_lcd(0x13);
+transfer_data_lcd(0x15);
+transfer_data_lcd(0x17);
+transfer_data_lcd(0x19);
+transfer_data_lcd(0x1b);
+transfer_data_lcd(0x1d);
+transfer_data_lcd(0x1f);
+transfer_command_lcd(0x31);//EXT=1
+transfer_command_lcd(0xf0);//Without this instruction, the voltage will be increased slowly. 0.5s
+transfer_data_lcd(0x0f);
+transfer_data_lcd(0x0f);
+transfer_data_lcd(0x0f);
+transfer_data_lcd(0x0f);
+transfer_command_lcd(0x30);//EXT=0
+transfer_command_lcd(0x75);//Page Address setting
+transfer_data_lcd(0X00);// XS=0
+transfer_data_lcd(0X28);// XE=159 0x28
+transfer_command_lcd(0x15);//Clumn Address setting
+transfer_data_lcd(0X00);// XS=0
+transfer_data_lcd(0Xff);// XE=256
+transfer_command_lcd(0xBC);//Data scan direction
+transfer_data_lcd(0x00);//MX.MY=Normal
+transfer_ command_lcd (0xA6);
+transfer_command_lcd(0xCA);//Display Control
+transfer_data_lcd(0X00);//
+transfer_data_lcd(0X9F);//Duty=160
+transfer_data_lcd(0X20);//Nline=off
+transfer_command_lcd(0xF0);//Display Mode
+transfer_data_lcd(0X10);//10=Monochrome Mode,11=4Gray
+transfer_command_lcd(0x81);//EV control
+transfer_data_lcd(0x1d);//Fine-tune the contrast value, 0x00~0x3f
+transfer_data_lcd(0x04);//Coarse contrast adjustment 0x00~0x07
+transfer_command_lcd(0x20);//Power control
+transfer_data_lcd(0x0B);//D0=regulator ; D1=follower ; D3=booste,
+on:1 off:0
+delay(20);
+transfer_command_lcd(0xAF);     //Display on
+
+*/
+
+static const uint8_t u8x8_d_st75161_jlx160160_init_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_DLY(20),
+  
+/*  
+U8X8_C( 0x030 ), // Extension Command 1
+U8X8_C( 0x06E ),
+
+U8X8_C( 0x031 ), // Extension Command 2
+U8X8_CA( 0x0d7, 0x09f), // Set auto-read instruction, Disable Auto Read
+
+U8X8_CA( 0x0e0 ,0x000), // Enable OTP Read
+U8X8_DLY(10),
+
+U8X8_C( 0x0e3 ), // OTP Read
+U8X8_DLY(20),
+U8X8_C(0xe1), // OTP Control Out
+*/
+  
+  
+  
+  
+  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( 0x000 ),				/* Bias: 0: 1/14, 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( 0x031 ),				/* select 01 commands */
+  U8X8_CA(0x51, 0xfb), // Booster Level x10
+  U8X8_CAAAA(0xf0, 15, 15, 15, 15),		/* Frame Rate Temparature Range */
+  
+  
+  U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CAA(0x75, 0, 0x28),		/* row range 0..159*/
+  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 */
+  U8X8_A( 0x20 ),				/* nline off */ 
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */ 
+  U8X8_CA( 0x0f0, 0x010 ),		/* monochrome mode  = 0x010, graylevel = 0x011*/
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CAA( 0x81, 0x1d, 0x04 ),	/* Volume control */
+
+  //U8X8_C( 0x030 ),				/* select 00 commands */
+  U8X8_CA( 0x020, 0x00b ),		/* Power control: Regulator, follower & booster on */
+  U8X8_DLY(100),
+
+  //U8X8_C( 0xaf ),
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+uint8_t u8x8_d_st75161_jlx160160(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 */
+              u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos+u8x8->x_offset));         // x offset is reused as y offset
+            
+              u8x8_cad_SendArg(u8x8, 0x027);
+              u8x8_cad_SendCmd(u8x8, 0x015 );	/* col */
+              u8x8_cad_SendArg(u8x8, x);
+              u8x8_cad_SendArg(u8x8, 0x9f);
+              u8x8_cad_SendCmd(u8x8, 0x05c );	
+              
+              do
+              {
+                c = ((u8x8_tile_t *)arg_ptr)->cnt;
+                ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+                c *= 8;
+                u8x8_cad_SendData(u8x8, c, ptr); 	
+                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 ST75161 */
+	    u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st75161_jlx160160_display_info);
+            return 1;
+        case U8X8_MSG_DISPLAY_INIT:
+	    u8x8_d_helper_display_init(u8x8);
+	    u8x8_cad_SendSequence(u8x8, u8x8_d_st75161_jlx160160_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;
+	case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+	    if ( arg_int == 0 )
+	    {
+	      u8x8_cad_SendSequence(u8x8, u8x8_d_st75161_jlx160160_flip0_seq);
+	      u8x8->x_offset = u8x8->display_info->default_x_offset;
+	    }
+	    else
+	    {
+	      u8x8_cad_SendSequence(u8x8, u8x8_d_st75161_jlx160160_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;
+}
+

+ 114 - 0
components/u8g2/u8x8_d_st75256.c

@@ -1987,3 +1987,117 @@ uint8_t u8x8_d_st75256_jlx16080(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
   return 0;
 }
 
+/*=============================================*/
+/* 128x128  issue https://github.com/olikraus/u8g2/issues/2702*/
+
+static const u8x8_display_info_t u8x8_st75256_128x128_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 = */ 16,
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 0,	/* must be 0, because this is checked also for normal mode */
+  /* flipmode_x_offset = */ 0,		/* used as y offset */
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 128
+};
+
+
+static const uint8_t u8x8_d_st75256_128x128_init_seq[] = {
+    U8X8_START_TRANSFER(),
+    U8X8_DLY(10),               // 10ms delay
+
+    U8X8_C(0x30),               // Extension command 1
+    U8X8_C(0x6E),               // Enable Master
+
+    U8X8_C(0x31),               // Extension command 2
+    U8X8_C(0xD7), U8X8_A(0x9F), // Disable Auto Read
+    U8X8_C(0xE0), U8X8_A(0x00), // Enable OTP Read
+    U8X8_DLY(10),
+    U8X8_C(0xE3),               // OTP Up-Load
+    U8X8_DLY(20),               // 20ms delay
+    U8X8_C(0xE1),               // OTP Control End
+
+    U8X8_C(0x30),               // Extension command 1
+    U8X8_C(0x94),               // Sleep Out
+    U8X8_C(0xAE),               // Display Off
+    U8X8_DLY(50),               // 50ms delay
+
+    U8X8_C(0x20),               // Power Control  
+    U8X8_A(0x0B),               // VB, VR, VF All on
+    U8X8_C(0x81), U8X8_A(0x1D), U8X8_A(0x04), // Set Vop (15.0V)
+
+    U8X8_C(0x31),               // Extension command 2
+    U8X8_C(0x32), U8X8_A(0x00), // Analog Set
+    U8X8_A(0x01),               // Booster efficiency level 1
+    U8X8_A(0x02),               // Bias 1/12
+    U8X8_C(0x51), U8X8_A(0xFA), // Booster Level x 8
+
+    U8X8_C(0x30),               // Extension command 1
+    U8X8_C(0xF0), U8X8_A(0x10), // Display Mode = Monochrome
+    U8X8_C(0xCA),               // Display Control
+    U8X8_A(0x00),               // CL Dividing Ratio = Not divided
+    U8X8_A(0x7F),               // Duty Set = 128
+    U8X8_A(0x3F),               
+    U8X8_C(0xBC), U8X8_A(0x00), // Data Scan Direction
+    U8X8_C(0xA6),               // Normal Display
+    U8X8_C(0x0C),               // Data Format = LSB on Top
+    U8X8_CAA(0x75, 0x00, 0x7F), // row range for 128 rows
+    U8X8_CAA(0x15, 0x00, 0x7F), // col range for 128 cols
+
+    U8X8_C(0x31),               // Extension command 2
+    U8X8_C(0x40),               // Internal Power Supply
+
+    U8X8_C(0x30),               // Extension command 1
+    U8X8_C(0xaf),               // Display On
+    U8X8_END_TRANSFER(),
+    U8X8_END()
+};
+
+
+uint8_t u8x8_d_st75256_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  if ( u8x8_d_st75256_256x128_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+    return 1;
+  if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
+  {
+    //u8x8_SetI2CAddress(u8x8, 0x078);		/* lowest I2C adr of the ST75256 */
+    u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st75256_128x128_display_info);
+    return 1;
+  }
+  else if ( msg == U8X8_MSG_DISPLAY_INIT )
+  {
+    u8x8_d_helper_display_init(u8x8);
+    u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_128x128_init_seq);    
+    return 1;
+  }
+  else if  ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
+  {
+    if ( arg_int == 0 )
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx256128_flip0_seq);
+      u8x8->x_offset = u8x8->display_info->default_x_offset;
+    }
+    else
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st75256_jlx256128_flip1_seq);
+      u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+    }
+    return 1;
+  }
+  return 0;
+}
+
+

File diff ditekan karena terlalu besar
+ 304 - 156
components/u8g2/u8x8_d_st7567.c


+ 76 - 0
components/u8g2/u8x8_d_st7571.c

@@ -36,6 +36,7 @@
   
   https://github.com/olikraus/u8g2/issues/921
   https://github.com/olikraus/u8g2/issues/1575          128x96
+  https://github.com/olikraus/u8g2/issues/2575          another 128x96 display
 
 */
 
@@ -361,3 +362,78 @@ uint8_t u8x8_d_st7571_128x96(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
   }
   return 1;
 }
+
+
+/*===================================================*/
+/*
+  ccsb4736w g12896 display
+
+  https://github.com/olikraus/u8g2/issues/2575
+
+  reusing u8x8_st7571_128x96_display_info
+
+*/
+static const uint8_t u8x8_d_st7571_g12896_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+
+  
+  U8X8_C(0xAE), 				// Display OFF
+  U8X8_C(0x38), 				// Mode Set  
+  //U8X8_C(0xB8), 				// FR=1011 (85Hz), BE[1:0]=10, level 3 booster
+  U8X8_C(0x94),                                 // 128x96: 75 Hz 
+  
+  U8X8_C(0xA0), 				// ADC select
+  U8X8_C(0xC8), 				// SHL select
+  U8X8_CA(0x44, 0x00), 		// 128x96: COM0 register  https://github.com/olikraus/u8g2/issues/2575
+  U8X8_CA(0x40, 0x00), 		// 128x96 datasheet
+  
+  U8X8_C(0xAB), 				// OSC ON  
+  U8X8_C(0x27), 				// 128x96: Voltage regulator
+  U8X8_CA(0x81, 0x28), 		// 128x96: Volume
+  U8X8_C(0x57), 				// 128x96: LCD Bias: 1/12 
+  U8X8_CA(0x48, 0x61), 		// 128x96: Duty 1/96
+  
+  U8X8_C(0x2C), 				// Power Control, VC: ON, VR: OFF, VF: OFF
+  U8X8_DLY(200),
+  U8X8_C(0x2E), 				// Power Control, VC: ON, VR: ON, VF: OFF
+  U8X8_DLY(200),
+  U8X8_C(0x2F), 				// Power Control, VC: ON, VR: ON, VF: ON
+  U8X8_DLY(10),
+
+  U8X8_C(0x7B), 				// command set 3
+  U8X8_C(0x11), 				// black white mode
+  U8X8_C(0x00), 				// exit command set 3
+
+
+  U8X8_C(0xA6), 				// Display Inverse OFF
+  U8X8_C(0xA4), 				// Disable Display All Pixel ON
+
+  //U8X8_C(0xAF), 				// Display on
+
+
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()           			/* end of sequence */
+};
+
+
+uint8_t u8x8_d_st7571_g12896(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+    
+  if ( u8x8_d_st7571_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_st7571_g12896_init_seq); 
+      break;
+    case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+      u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7571_128x96_display_info);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}

+ 243 - 0
components/u8g2/u8x8_d_st7586s_md240128.c

@@ -0,0 +1,243 @@
+/*
+  u8x8_d_st7586s_md240128.c 
+
+  Display: 240x128 pixel, 
+  ST7586s: 384 x 160 x 2
+
+  takeover from https://github.com/olikraus/u8g2/issues/2363
+  
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+  
+  Copyright (c) 2024, 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_ymc240160_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 -> 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_ymc240160_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C(0x036),  /* Scan Direction Setting */
+  U8X8_A(0x080),  /* COM0 -> COM159 SEG383 -> SEG0 */
+  U8X8_C(0x037),  /* Start line 0 */
+  U8X8_A(0x020),
+  U8X8_END_TRANSFER(),  /* disable chip */
+  U8X8_END()            /* end of sequence */
+};
+
+static const uint8_t u8x8_d_st7586s_ymc240160_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,0x036,0x01),// Vop = 136h data sheet suggested 0x0145 but this caused streaks
+
+  U8X8_CA(0x0C3,0x000), // BIAS = 1/14
+
+  U8X8_CA(0x0C4,0x007), // Booster = x8
+
+  U8X8_CA(0x0D0,0x01D), // Enable Analog Circuit
+
+  U8X8_CA(0x0B3,0x000), // Set FOSC divider
+
+  U8X8_CA(0x0B5,0x000), // N-Line = 0
+
+  U8X8_C(0x039), // 0x39 Monochrome mode. 0x38 - gray Mode
+
+  U8X8_C(0x03A), // Enable DDRAM Interface
+  U8X8_A(0x002), // monochrome and 4-level
+
+  U8X8_C(0x036), // Scan Direction Setting
+  U8X8_A(0x000), // COM:C0->C159   SEG: SEG0->SEG383
+
+  U8X8_C(0x0B1), // First output COM
+  U8X8_A(0x000), // 
+  
+  U8X8_C(0x0B0), // Duty Setting (num rows - 1)
+  U8X8_A(0x07F), 
+
+  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(0x04F), // 80*3=240 pixels
+
+  U8X8_C(0x02B), // Row Address Setting
+  U8X8_A(0x000), // ROW0 -> ROW127
+  U8X8_A(0x000), //
+  U8X8_A(0x000), //
+  U8X8_A(0x07F), // 128 pixels
+
+  U8X8_C(0x029), // Display ON
+  U8X8_END_TRANSFER(),/* disable chip */
+  U8X8_END()  /* end of sequence */
+};
+
+static const u8x8_display_info_t u8x8_st7586s_ymc240160_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+
+  /* post_chip_enable_wait_ns = */ 5,
+  /* pre_chip_disable_wait_ns = */ 5,
+  /* reset_pulse_width_ms = */ 1,
+  /* post_reset_wait_ms = */ 6,
+  /* sda_setup_time_ns = */ 20,
+  /* sck_pulse_width_ns = */  100,  /* datasheet ST7586S */
+  /* sck_clock_hz = */ 8000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* ST7586+Atmega128RFA1 works with 8MHz */
+  /* spi_mode = */ 3,   /* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 20, /* datasheet suggests min 20 */
+  /* write_pulse_width_ns = */ 40,
+  /* tile_width = */ 30,
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 0,  /* abused as flag to know if we are flipped */
+  /* flipmode_x_offset = */ 1, /* as pixel order different for normal/flipped  */
+  /* pixel_width = */ 240,
+  /* pixel_height = */ 128
+};
+
+/*  takeover from https://github.com/olikraus/u8g2/issues/2363 */
+uint8_t u8x8_d_st7586s_md240128(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];
+//  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_ymc240160_init_seq);
+    break;
+  case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+    u8x8_d_helper_display_setup_memory(u8x8, &u8x8_st7586s_ymc240160_display_info);
+    break;
+  case U8X8_MSG_DISPLAY_SET_FLIP_MODE:
+  	if ( arg_int == 0 )
+    {
+       u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_ymc240160_flip0_seq);
+       u8x8->x_offset = u8x8->display_info->default_x_offset;
+    }
+    else
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_st7586s_ymc240160_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;
+}
+

+ 44 - 10
components/u8g2/u8x8_d_st7920.c

@@ -52,7 +52,7 @@ static const uint8_t u8x8_d_st7920_init_seq[] = {
   U8X8_C(0x006),		                /* Entry mode: Cursor move to right ,DDRAM address counter (AC) plus 1, no shift  */  
   U8X8_C(0x002),		                /* disable scroll, enable CGRAM adress  */
   U8X8_C(0x001),		                /* clear RAM, needs 1.6 ms */
-  U8X8_DLY(4),					/* delay 2ms */
+  U8X8_DLY(10),					/* delay 10ms */
 
   
   U8X8_END_TRANSFER(),             	/* disable chip */
@@ -153,6 +153,49 @@ uint8_t u8x8_d_st7920_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
 }
 
 
+/*=== 128x32 === */
+/* https://github.com/olikraus/u8g2/issues/2241 */
+
+static const u8x8_display_info_t u8x8_st7920_128x32_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 = */ 16,
+  /* tile_height = */ 4,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 32
+};
+
+
+uint8_t u8x8_d_st7920_128x32(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_128x32_display_info);
+      break;
+    default:
+      return u8x8_d_st7920_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+
+
 /*=== 144x32 === */
 /* https://github.com/olikraus/u8g2/issues/209 */
 
@@ -196,13 +239,6 @@ uint8_t u8x8_d_st7920_144x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
 }
 
 
-
-
-
-
-
-
-
 /*=== 160x32 === */
 /* https://github.com/olikraus/u8g2/issues/1873, POWERTIP PG-16032LRU-BWH-H-P2 */
 
@@ -231,7 +267,6 @@ static const u8x8_display_info_t u8x8_st7920_160x32_display_info =
   /* pixel_height = */ 32
 };
 
-
 uint8_t u8x8_d_st7920_160x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {
   switch(msg)
@@ -356,7 +391,6 @@ static const u8x8_display_info_t u8x8_st7920_256x32_display_info =
   /* pixel_width = */ 256,
   /* pixel_height = */ 32
 };
-  
 
 uint8_t u8x8_d_st7920_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
 {

+ 82 - 0
components/u8g2/u8x8_d_t6963.c

@@ -642,4 +642,86 @@ uint8_t u8x8_d_t6963_128x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
 }
   
 
+/*=============================================*/
+
+static const u8x8_display_info_t u8x8_t6963_128x160_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 = */ 20,
+  /* default_x_offset = */ 0,
+  /* flipmode_x_offset = */ 0,
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 160
+};
+
+/* 128x160 */
+static const uint8_t u8x8_d_t6963_128x160_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_128x160(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_128x160_display_info);
+      break;
+    case U8X8_MSG_DISPLAY_INIT:
+      u8x8_d_helper_display_init(u8x8);
+      u8x8_cad_SendSequence(u8x8, u8x8_d_t6963_128x160_init_seq);
+      break;
+    default:
+      return u8x8_d_t6963_common(u8x8, msg, arg_int, arg_ptr);
+  }
+  return 1;
+}
+  
   

+ 93 - 0
components/u8g2/u8x8_d_uc1604.c

@@ -144,6 +144,99 @@ uint8_t u8x8_d_uc1604_common(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
   return 1;
 }
 
+/*================================================*/
+/* JLX12864 */
+
+/* 
+  timings from uc1604 
+
+  UC1604 has two chip select inputs (CS0 and CS1).
+  CS0 is low active, CS1 is high active. It will depend on the display
+  module whether the display has a is low or high active chip select.
+
+*/
+static const u8x8_display_info_t u8x8_uc1604_128x64_display_info =
+{
+  /* chip_enable_level = */ 0,	/* JLX12864G uses CS0, which is low active CS*/
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 20,	
+  /* pre_chip_disable_wait_ns = */ 20,	
+  /* reset_pulse_width_ms = */ 1, 	
+  /* post_reset_wait_ms = */ 10, 	
+  /* sda_setup_time_ns = */ 30,		
+  /* sck_pulse_width_ns = */ 65,	/* half of cycle time  */
+  /* sck_clock_hz = */ 8000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,
+  /* data_setup_time_ns = */ 30,	
+  /* write_pulse_width_ns = */ 35,	
+  /* tile_width = */ 16,		/* width of 24*8=192 pixel */
+  /* tile_height = */ 8,
+  /* default_x_offset = */ 0,	/* reused as y page offset */
+  /* flipmode_x_offset = */ 0,	/* reused as y page offset */
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 64
+};
+
+static const uint8_t u8x8_d_uc1604_jlx12864_init_seq[] = {
+    
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+
+  U8X8_C(0x0e2),            			/* soft reset */
+  U8X8_DLY(200),
+  U8X8_DLY(200),
+
+  U8X8_C(0x02f),            			/* power on, Bit 2 PC2=1 (internal charge pump), Bits 0/1: cap of panel */
+  U8X8_DLY(200),
+  U8X8_DLY(200),
+  
+  U8X8_CA(0x081, 0x038),		/* set contrast, JLX19264G suggestion: 0x045 */
+  U8X8_C(0x0eb),            			/* LCD bias Bits 0/1: 00=6 01=7, 10=8, 11=9 */
+
+  
+  //U8X8_C(0x023),            			/* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
+  //U8X8_C(0x027),            			/* Bit 0/1: Temp compenstation, Bit 2: Multiplex Rate 0=96, 1=128 */
+
+  U8X8_C(0x0c2),            			/* Map control, Bit 2: MY=1, Bit 1: MX=0 */
+  U8X8_C(0x0a0),            			/* 0xa0: 76Hz FPS, controller default: 0x0a1: 95Hz FPS */
+  
+  
+  U8X8_C(0x040),            			/* set scroll line to 0 */
+  U8X8_C(0x089),            			/* RAM access control (controller default: 0x089)*/
+  
+  
+  U8X8_C(0x000),		                /* column low nibble */
+  U8X8_C(0x010),		                /* column high nibble */  
+  U8X8_C(0x0b0),		                /* page adr  */
+  
+  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+uint8_t u8x8_d_uc1604_jlx12864(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  /* call common procedure first and handle messages there */
+  if ( u8x8_d_uc1604_common(u8x8, msg, arg_int, arg_ptr) == 0 )
+  {
+    /* msg not handled, then try here */
+    switch(msg)
+    {
+      case U8X8_MSG_DISPLAY_SETUP_MEMORY:
+	u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1604_128x64_display_info);
+	break;
+      case U8X8_MSG_DISPLAY_INIT:
+	u8x8_d_helper_display_init(u8x8);
+	u8x8_cad_SendSequence(u8x8, u8x8_d_uc1604_jlx12864_init_seq);
+	break;
+      default:
+	return 0;		/* msg unknown */
+    }
+  }
+  return 1;
+}
+
 /*================================================*/
 /* JLX19264 */
 

+ 457 - 0
components/u8g2/u8x8_d_uc1628.c

@@ -0,0 +1,457 @@
+/*
+
+  u8x8_d_uc1628.c
+
+  Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
+
+  Copyright (c) 2017, olikraus@gmail.com
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without modification, 
+  are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this list 
+    of conditions and the following disclaimer.
+    
+  * Redistributions in binary form must reproduce the above copyright notice, this 
+    list of conditions and the following disclaimer in the documentation and/or other 
+    materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
+  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
+
+  UC1628: Monochrome 163x256 driver
+
+  CAD: 011
+
+*/
+
+#include "u8x8.h"
+
+static const uint8_t u8x8_d_uc1628_powersave0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CA( 0x0c9, 0x0ad ),				/* display enable */  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_uc1628_powersave1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_CA( 0x0c9, 0x0ac ),				/* display disable */  
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+static const uint8_t u8x8_d_uc1628_flip0_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C( 0x0c4 ),	
+  U8X8_END_TRANSFER(),             	
+  U8X8_END()             			/* end of sequence */
+};
+
+static const uint8_t u8x8_d_uc1628_flip1_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  U8X8_C( 0x0c2 ),				
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+static uint8_t u8x8_d_uc1628_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_st75256_256x128_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_st75256_256x128_init_seq);    
+      break;
+    */
+    case U8X8_MSG_DISPLAY_SET_POWER_SAVE:
+      if ( arg_int == 0 )
+        u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_powersave0_seq);
+      else
+        u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_powersave1_seq);
+
+      break;
+#ifdef U8X8_WITH_SET_CONTRAST
+    case U8X8_MSG_DISPLAY_SET_CONTRAST:
+
+      u8x8_cad_StartTransfer(u8x8);
+      
+      u8x8_cad_SendCmd(u8x8, 0x081 );  /* volume control */
+      u8x8_cad_SendArg(u8x8, 0 );	/* always 0 */
+      u8x8_cad_SendArg(u8x8, arg_int);		/* 8 bit */
+      
+      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;
+    
+      // TODO: u8x8->x_offset IS MISSING here
+
+      u8x8_cad_SendCmd(u8x8, 0x004 );	/* col */
+      u8x8_cad_SendArg(u8x8, x);
+    
+      u8x8_cad_SendCmd(u8x8, 0x060 );	/* row */
+      u8x8_cad_SendArg(u8x8, (((u8x8_tile_t *)arg_ptr)->y_pos));	
+    
+      u8x8_cad_SendCmd(u8x8, 0x001 );	        // write data
+          
+      do
+      {
+        c = ((u8x8_tile_t *)arg_ptr)->cnt;
+        ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
+        /* SendData can not handle more than 255 bytes, treat c > 31 correctly  */
+        if ( c > 31 )
+        {
+          u8x8_cad_SendData(u8x8, 248, ptr); 	/* 31*8=248 */
+          ptr+=248;
+          c -= 31;
+        }
+        
+        u8x8_cad_SendData(u8x8, c*8, ptr); 	
+        arg_int--;
+      } while( arg_int > 0 );
+      
+      u8x8_cad_EndTransfer(u8x8);
+      break;
+    default:
+      return 0;
+  }
+  return 1;
+}
+
+/*=============================================*/
+/* 256x128, https://github.com/olikraus/u8g2/issues/2260 */
+
+static const u8x8_display_info_t u8x8_uc1628_256x128_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 10,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 5, 	
+  /* post_reset_wait_ms = */ 5, 		/**/
+  /* sda_setup_time_ns = */ 25,		/* */
+  /* sck_pulse_width_ns = */ 100,	/*  */
+  /* sck_clock_hz = */ 4000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,	/* 400KHz */
+  /* data_setup_time_ns = */ 45,
+  /* write_pulse_width_ns = */ 125,	
+  /* tile_width = */ 32,
+  /* tile_height = */ 16,
+  /* default_x_offset = */ 0,	/*  */
+  /* flipmode_x_offset = */ 0,		/*  */
+  /* pixel_width = */ 256,
+  /* pixel_height = */ 128
+};
+
+static const uint8_t u8x8_d_uc1628_256x128_init_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_DLY(20),
+
+  U8X8_C( 0x010 ),				/* Termp.: Reset default */
+  U8X8_C( 0x012 ),				/* Termp.: Reset default */
+  U8X8_C( 0x014 ),				/* Termp.: Reset default  */
+  
+  /* assign temperature independent framerate */
+  /* 0x00d = 81,9Hz (reset default) */
+  /* 0x000 = 40.0 Hz (min) */
+  /* 0x01f = 140.0 Hz (max) */
+  
+  U8X8_CAA( 0x016, 0x000, 0x00d ),				/* 1st arg: temp. point, 2nd arg: frame rate */
+
+  U8X8_CA( 0x040, 0x000 ),				/*  scroll line */
+
+  U8X8_C( 0x020 ),				/* temp compensation */
+  U8X8_C( 0x02d ),				/* charge pump control */
+  U8X8_C( 0x0eb ),				/* LCD Bias: 0xe8=6, ... 0xeb=12 ... 0xed=14  */
+
+  U8X8_CAA( 0x081, 0x000, 0x048 ),	        /*  Contrast, 1st arg is always 0 */
+
+  U8X8_CA( 0x0b8, 0x000 ),				/*  OTP control: Idle & Ignore */
+
+  U8X8_CA( 0x0f1, 0x07f ),				/*  set COM end */
+  U8X8_CA( 0x0f2, 0x000 ),				/*  set partial display start */
+  U8X8_CA( 0x0f3, 0x07f ),				/*  set partial display end */
+  
+  U8X8_C( 0x088 ),				/*  auto increment control */
+
+  U8X8_C( 0x0c4 ),                      /* XY mirror in bit 1 & 2 */	
+
+  U8X8_DLY(100),
+
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+uint8_t u8x8_d_uc1628_256x128(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  if ( u8x8_d_uc1628_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+    return 1;
+  if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
+  {
+    u8x8_SetI2CAddress(u8x8, 0x070);		/* lowest I2C adr of the UC1628 */
+    u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1628_256x128_display_info);
+    return 1;
+  }
+  else if ( msg == U8X8_MSG_DISPLAY_INIT )
+  {
+    u8x8_d_helper_display_init(u8x8);
+    u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_256x128_init_seq);    
+    return 1;
+  }
+  else if  ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
+  {
+    if ( arg_int == 0 )
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip0_seq);
+      u8x8->x_offset = u8x8->display_info->default_x_offset;
+    }
+    else
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip1_seq);
+      u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+    }
+    return 1;
+  }
+  return 0;
+}
+
+
+/*=============================================*/
+/* 256x32, https://github.com/olikraus/u8g2/issues/2260 */
+
+static const u8x8_display_info_t u8x8_uc1628_256x32_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 10,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 5, 	
+  /* post_reset_wait_ms = */ 5, 		/**/
+  /* sda_setup_time_ns = */ 25,		/* */
+  /* sck_pulse_width_ns = */ 100,	/*  */
+  /* sck_clock_hz = */ 4000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,	/* 400KHz */
+  /* data_setup_time_ns = */ 45,
+  /* write_pulse_width_ns = */ 125,	
+  /* tile_width = */ 32,
+  /* tile_height = */ 4,
+  /* default_x_offset = */ 0,	/*  */
+  /* flipmode_x_offset = */ 0,		/*  */
+  /* pixel_width = */ 256,
+  /* pixel_height = */ 32
+};
+
+static const uint8_t u8x8_d_uc1628_256x32_init_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_DLY(20),
+
+  U8X8_C( 0x010 ),				/* Termp.: Reset default */
+  U8X8_C( 0x012 ),				/* Termp.: Reset default */
+  U8X8_C( 0x014 ),				/* Termp.: Reset default  */
+  
+  /* assign temperature independent framerate */
+  /* 0x00d = 81,9Hz (reset default) */
+  /* 0x000 = 40.0 Hz (min) */
+  /* 0x01f = 140.0 Hz (max) */
+  
+  U8X8_CAA( 0x016, 0x000, 0x00d ),				/* 1st arg: temp. point, 2nd arg: frame rate */
+
+  U8X8_CA( 0x040, 0x000 ),				/*  scroll line */
+
+  U8X8_C( 0x020 ),				/* temp compensation */
+  U8X8_C( 0x02d ),				/* charge pump control */
+  U8X8_C( 0x0e8 ),				/* LCD Bias: 0xe8=6, ... 0xeb=12 ... 0xed=14  */
+
+  U8X8_CAA( 0x081, 0x000, 0x048 ),	        /*  Contrast, 1st arg is always 0 */
+
+  U8X8_CA( 0x0b8, 0x000 ),				/*  OTP control: Idle & Ignore */
+
+  U8X8_CA( 0x0f1, 0x01f ),				/*  set COM end */
+  U8X8_CA( 0x0f2, 0x000 ),				/*  set partial display start */
+  U8X8_CA( 0x0f3, 0x07f ),				/*  set partial display end */
+  
+  U8X8_C( 0x088 ),				/*  auto increment control */
+
+  U8X8_C( 0x0c4 ),                      /* XY mirror in bit 1 & 2 */	
+
+  U8X8_DLY(100),
+
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+uint8_t u8x8_d_uc1628_256x32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  if ( u8x8_d_uc1628_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+    return 1;
+  if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
+  {
+    u8x8_SetI2CAddress(u8x8, 0x070);		/* lowest I2C adr of the UC1628 */
+    u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1628_256x32_display_info);
+    return 1;
+  }
+  else if ( msg == U8X8_MSG_DISPLAY_INIT )
+  {
+    u8x8_d_helper_display_init(u8x8);
+    u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_256x32_init_seq);    
+    return 1;
+  }
+  else if  ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
+  {
+    if ( arg_int == 0 )
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip0_seq);
+      u8x8->x_offset = u8x8->display_info->default_x_offset;
+    }
+    else
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip1_seq);
+      u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+    }
+    return 1;
+  }
+  return 0;
+}
+
+
+/*=============================================*/
+/* 128x64, https://github.com/olikraus/u8g2/issues/2260 
+
+  2 Oct 2023: Probably the LCD Bias is wrong, it should be reduced, maybe 0xea or so
+  Moreover the COM end should be halfed (0x03f) --> Done, but not tested
+
+*/
+
+static const u8x8_display_info_t u8x8_uc1628_128x64_display_info =
+{
+  /* chip_enable_level = */ 0,
+  /* chip_disable_level = */ 1,
+  
+  /* post_chip_enable_wait_ns = */ 10,
+  /* pre_chip_disable_wait_ns = */ 10,
+  /* reset_pulse_width_ms = */ 5, 	
+  /* post_reset_wait_ms = */ 5, 		/**/
+  /* sda_setup_time_ns = */ 25,		/* */
+  /* sck_pulse_width_ns = */ 100,	/*  */
+  /* sck_clock_hz = */ 4000000UL,	/* since Arduino 1.6.0, the SPI bus speed in Hz. Should be  1000000000/sck_pulse_width_ns */
+  /* spi_mode = */ 0,		/* active high, rising edge */
+  /* i2c_bus_clock_100kHz = */ 4,	/* 400KHz */
+  /* data_setup_time_ns = */ 45,
+  /* write_pulse_width_ns = */ 125,	
+  /* tile_width = */ 16,
+  /* tile_height = */ 8,
+  /* default_x_offset = */ 0,	/*  */
+  /* flipmode_x_offset = */ 0,		/*  */
+  /* pixel_width = */ 128,
+  /* pixel_height = */ 64
+};
+
+static const uint8_t u8x8_d_uc1628_128x64_init_seq[] = {
+  U8X8_START_TRANSFER(),             	/* enable chip, delay is part of the transfer start */
+  
+  U8X8_DLY(20),
+
+  U8X8_C( 0x010 ),				/* Termp.: Reset default */
+  U8X8_C( 0x012 ),				/* Termp.: Reset default */
+  U8X8_C( 0x014 ),				/* Termp.: Reset default  */
+  
+  /* assign temperature independent framerate */
+  /* 0x00d = 81,9Hz (reset default) */
+  /* 0x000 = 40.0 Hz (min) */
+  /* 0x01f = 140.0 Hz (max) */
+  
+  U8X8_CAA( 0x016, 0x000, 0x00d ),				/* 1st arg: temp. point, 2nd arg: frame rate */
+
+  U8X8_CA( 0x040, 0x000 ),				/*  scroll line */
+
+  U8X8_C( 0x020 ),				/* temp compensation */
+  U8X8_C( 0x02d ),				/* charge pump control */
+  U8X8_C( 0x0eb ),				/* LCD Bias: 0xe8=6, ... 0xeb=12 ... 0xed=14  */
+
+  U8X8_CAA( 0x081, 0x000, 0x048 ),	        /*  Contrast, 1st arg is always 0 */
+
+  U8X8_CA( 0x0b8, 0x000 ),				/*  OTP control: Idle & Ignore */
+
+  U8X8_CA( 0x0f1, 0x03f ),				/*  set COM end */
+  U8X8_CA( 0x0f2, 0x000 ),				/*  set partial display start */
+  U8X8_CA( 0x0f3, 0x07f ),				/*  set partial display end */
+  
+  U8X8_C( 0x088 ),				/*  auto increment control */
+
+  U8X8_C( 0x0c4 ),                      /* XY mirror in bit 1 & 2 */	
+
+  U8X8_DLY(100),
+
+  U8X8_END_TRANSFER(),             	/* disable chip */
+  U8X8_END()             			/* end of sequence */
+};
+
+
+uint8_t u8x8_d_uc1628_128x64(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
+{
+  if ( u8x8_d_uc1628_generic(u8x8, msg, arg_int, arg_ptr) != 0 )
+    return 1;
+  if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY )
+  {
+    u8x8_SetI2CAddress(u8x8, 0x070);		/* lowest I2C adr of the UC1628 */
+    u8x8_d_helper_display_setup_memory(u8x8, &u8x8_uc1628_128x64_display_info);
+    return 1;
+  }
+  else if ( msg == U8X8_MSG_DISPLAY_INIT )
+  {
+    u8x8_d_helper_display_init(u8x8);
+    u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_128x64_init_seq);    
+    return 1;
+  }
+  else if  ( msg == U8X8_MSG_DISPLAY_SET_FLIP_MODE )
+  {
+    if ( arg_int == 0 )
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip0_seq);
+      u8x8->x_offset = u8x8->display_info->default_x_offset;
+    }
+    else
+    {
+      u8x8_cad_SendSequence(u8x8, u8x8_d_uc1628_flip1_seq);
+      u8x8->x_offset = u8x8->display_info->flipmode_x_offset;
+    }
+    return 1;
+  }
+  return 0;
+}
+
+

+ 3 - 3
components/u8g2/u8x8_display.c

@@ -64,7 +64,7 @@ void u8x8_d_helper_display_setup_memory(u8x8_t *u8x8, const u8x8_display_info_t
 void u8x8_d_helper_display_init(u8x8_t *u8x8)
 {
       /* 2) apply port directions to the GPIO lines and apply default values for the IO lines*/
-      u8x8_gpio_Init(u8x8);
+      u8x8_gpio_Init(u8x8);             /* macro, which calls gpio_and_delay_cb with U8X8_MSG_GPIO_AND_DELAY_INIT */
       u8x8_cad_Init(u8x8);              /* this will also call U8X8_MSG_BYTE_INIT, byte init will NOT call GPIO_INIT */
 
       /* 3) do reset */
@@ -108,8 +108,8 @@ void u8x8_SetupMemory(u8x8_t *u8x8)
 */
 void u8x8_InitInterface(u8x8_t *u8x8)
 {
-  u8x8_gpio_Init(u8x8);
-  u8x8_cad_Init(u8x8);              /* this will also call U8X8_MSG_BYTE_INIT, byte init will NOT call GPIO_INIT */
+  u8x8_gpio_Init(u8x8);          /* macro, which calls gpio_and_delay_cb with U8X8_MSG_GPIO_AND_DELAY_INIT */
+  u8x8_cad_Init(u8x8);              /* this will also call U8X8_MSG_BYTE_INIT, byte init will NOT call GPIO_INIT, which alread is called in the prev step */
 }
 
 /*

+ 42 - 0
components/u8g2/u8x8_u8toa.c

@@ -65,3 +65,45 @@ const char *u8x8_u8toa(uint8_t v, uint8_t d)
   return u8x8_u8toap(buf, v) + d;
 }
 
+const char *u8x8_s8toa(int8_t v, uint8_t d)
+{
+  static char buf[5];
+  uint16_t u = v;
+  buf[0] = '+';
+  if ( v < 0 )
+  {
+    buf[0] = '-';
+    u = -v;
+  }
+  u8x8_u8toap(buf+1, (uint8_t)u);
+  if ( d == 1 )
+  {
+    buf[1] = buf[3];
+    buf[2] = '\0';
+  }
+  else if ( d == 2 )
+  {
+    buf[1] = buf[2];
+    buf[2] = buf[3];
+    buf[3] = '\0';
+  }
+  return buf;
+}
+ 
+const char *u8x8_u8tox(uint8_t v, uint8_t d)
+{
+  const char hexdigit[]="0123456789ABCDEF";
+  static char buf[3];
+  if ( d == 1 )
+  {
+    buf[0] = hexdigit[v & 0xF];
+    buf[1] = '\0';
+  }
+  else if ( d == 2 )
+  {
+    buf[0] = hexdigit[v >> 4 & 0xF];
+    buf[1] = hexdigit[v & 0xF];
+    buf[2] = '\0';
+  }
+  return buf;
+}

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini