From f410b5772005a35bae24e3ca403e14a60f8a41e8 Mon Sep 17 00:00:00 2001 From: inmarket Date: Sun, 13 Aug 2017 20:07:39 +1000 Subject: [PATCH] Vastly improve UC8173 driver --- drivers/gdisp/UC8173/UC8173.h | 809 ------------------- drivers/gdisp/UC8173/board_UC8173_template.h | 36 +- drivers/gdisp/UC8173/gdisp_lld_UC8173.c | 608 ++++++++------ drivers/gdisp/UC8173/gdisp_lld_config.h | 5 +- 4 files changed, 409 insertions(+), 1049 deletions(-) diff --git a/drivers/gdisp/UC8173/UC8173.h b/drivers/gdisp/UC8173/UC8173.h index a38fd573..e0e97eeb 100644 --- a/drivers/gdisp/UC8173/UC8173.h +++ b/drivers/gdisp/UC8173/UC8173.h @@ -96,814 +96,5 @@ #define Initial_Counter 64 #define Temperature_LUT_Counter 672 -static uint8_t const _lut_None[] = { - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00 -}; - - -static uint8_t const _lut_KWvcom_DC_GU[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x0C, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -static uint8_t const _lut_KWvcom_DC_A2_240ms[] = { - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x0C, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -static uint8_t const _lut_KWvcom_DC_A2_120ms[] = { - 0x00, - 0x00, - 0x00, - 0x0C, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - - -static uint8_t const _lut_kw_GU[] = { - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x80, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - - -static uint8_t const _lut_kw_A2_240ms[] = { - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -static uint8_t const _lut_kw_A2_120ms[] = { - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x02, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - - -static uint8_t const _lut_KWvcom[] = { - 0x55, - 0x6A, - 0xA5, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x56, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0x0C, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; - -static uint8_t const _lut_kw[] = { - 0x41, 0x00, 0x00, 0x81, - 0x41, 0x00, 0x00, 0x81, - 0x41, 0x00, 0x00, 0x81, - 0x41, 0x00, 0x00, 0x81, - 0x41, 0x00, 0x00, 0x81, - 0x81, 0x00, 0x00, 0x82, - 0x81, 0x00, 0x00, 0x82, - 0x81, 0x00, 0x00, 0x82, - 0x81, 0x00, 0x00, 0x82, - 0x81, 0x00, 0x00, 0x82, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x42, 0x00, 0x00, 0x41, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x82, 0x00, 0x00, 0x42, - 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - - -static uint8_t const _lut_ft[] = { - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x55, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0xAA, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x5A, - 0x00, - 0xFF, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00 -}; #endif // _UC8173_H diff --git a/drivers/gdisp/UC8173/board_UC8173_template.h b/drivers/gdisp/UC8173/board_UC8173_template.h index f16205f4..dde70771 100644 --- a/drivers/gdisp/UC8173/board_UC8173_template.h +++ b/drivers/gdisp/UC8173/board_UC8173_template.h @@ -8,6 +8,26 @@ #ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H +// Define options for this driver +#define UC8173_REVERSEAXIS_Y FALSE +#define UC8173_REVERSEAXIS_X FALSE +#define UC8173_USE_OTP_LUT FALSE /* Use the LUT in the OTP - untested */ +#define UC8173_DEFAULT_MODE 0 /* Which entry in the mode table to start with */ +#define UC8173_CAN_READ FALSE /* Reading the controller chip is supported */ +#define UC8173_VCOM_VOLTAGE -2.80 /* Read this off the sticker on the back of the display or set UC8173_CAN_READ to have the chip read */ +#define UC8171_BORDER 0 /* 0 = Hi-Z, 1 = Black, 2 = White */ + +// Define the waveform table +#include "UC8173_waveform_examples.h" +static UC8173Lut UC8173_ModeTable[] = { + // 32 bytes, 512 bytes, 128 bytes, regal + { _lut_KWvcom_DC_A2_240ms, _lut_kw_A2_240ms, _lut_ft, FALSE }, + { _lut_KWvcom_DC_A2_120ms, _lut_kw_A2_120ms, _lut_ft, FALSE }, + { _lut_KWvcom_DC_GU, _lut_kw_GU, _lut_ft, TRUE }, + { _lut_KWvcom_GC, _lut_kw_GC, _lut_ft, FALSE } + // Add extra lines for other waveforms + }; + static GFXINLINE void init_board(GDisplay* g) { (void) g; @@ -24,6 +44,12 @@ static GFXINLINE void setpin_reset(GDisplay* g, bool_t state) (void) state; } +static GFXINLINE bool_t getpin_busy(GDisplay* g) +{ + (void)g; + return FALSE; +} + static GFXINLINE void acquire_bus(GDisplay* g) { (void) g; @@ -46,11 +72,19 @@ static GFXINLINE void write_data(GDisplay* g, uint8_t data) (void) data; } -static GFXINLINE void write_data_burst(GDisplay* g, uint8_t* data, uint16_t length) +static GFXINLINE void write_data_burst(GDisplay* g, uint8_t* data, unsigned length) { (void) g; (void) data; (void) length; } +#if UC8173_CAN_READ + static GFXINLINE uint8_t read_data(GDisplay* g) + { + (void)g; + return 0; + } +#endif + #endif /* _GDISP_LLD_BOARD_H */ diff --git a/drivers/gdisp/UC8173/gdisp_lld_UC8173.c b/drivers/gdisp/UC8173/gdisp_lld_UC8173.c index e65b74fa..88e2761e 100644 --- a/drivers/gdisp/UC8173/gdisp_lld_UC8173.c +++ b/drivers/gdisp/UC8173/gdisp_lld_UC8173.c @@ -12,8 +12,6 @@ #define GDISP_DRIVER_VMT GDISPVMT_UC8173 #include "gdisp_lld_config.h" #include "../../../src/gdisp/gdisp_driver.h" -#include "UC8173.h" -#include "board_UC8173.h" #if defined(GDISP_SCREEN_HEIGHT) || defined(GDISP_SCREEN_HEIGHT) #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT @@ -25,172 +23,198 @@ #undef GDISP_SCREEN_HEIGHT #endif -#define GDISP_SCREEN_HEIGHT 240 -#define GDISP_SCREEN_WIDTH 240 +/*------------------ Load the board file ------------------*/ +typedef struct UC8173Lut { + uint8_t const *lutVCOM; // 32 bytes + uint8_t const *lutFW; // 512 bytes + uint8_t const *lutFT; // 128 bytes + bool_t regal; + } UC8173Lut; -#define PRIV(g) ((UC8173_Private*)((g)->priv)) -#define FRAMEBUFFER(g) ((uint8_t *)(PRIV(g)+1)) -#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) +#include "board_UC8173.h" -#if GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_MONO - #define LINE_BYTES (GDISP_SCREEN_WIDTH/8) - #define WRITEBUFCMD DTM4 - #define xyaddr(x, y) (((x)>>3) + ((y) * LINE_BYTES)) - //#define xybit(x, c) ((c) << ((x) & 7)) // This one has the wrong order of the pixels inside the byte - #define xybit(x, c) ((c) << (7-((x) & 7))) -#elif GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_GRAY4 - #define LINE_BYTES (GDISP_SCREEN_WIDTH/4) - #define WRITEBUFCMD DTM2 // NOT SURE THIS IS RIGHT - MAY NEED TO USE DTM0 and then send a refresh??? - #define xyaddr(x, y) (((x)>>2) + ((y) * LINE_BYTES)) - //#define xybit(x, c) ((c) << (((x) & 3)<<1)) // This one has the wrong order of the pixels inside the byte - #define xybit(x, c) ((c) << (6-((x) & 3)<<1)) -#else - #error "UC8173: Unsupported driver color format" +/*------------------ Default UC8173 parameters ------------------*/ +#ifndef UC8173_REVERSEAXIS_Y + #define UC8173_REVERSEAXIS_Y FALSE #endif +#ifndef UC8173_REVERSEAXIS_X + #define UC8173_REVERSEAXIS_X FALSE +#endif +#ifndef UC8173_DEFAULT_MODE + #define UC8173_DEFAULT_MODE 0 +#endif +#ifndef UC8173_USE_OTP_LUT + #define UC8173_USE_OTP_LUT FALSE +#endif +#ifndef UC8173_CAN_READ + #define UC8173_CAN_READ FALSE +#endif +#ifdef UC8173_VCOM_VOLTAGE + #define UC8173_VCOM_VOLTAGEBYTE (((UC8173_VCOM_VOLTAGE) + 0.1)/-0.05) +#endif +#ifndef UC8171_BORDER + #define UC8171_BORDER 0 /* 0 = Hi-Z, 1 = Black, 2 = White */ +#endif +#ifndef UC8173_INIT_REAL_LUT + #define UC8173_INIT_REAL_LUT TRUE +#endif +#define UC8173_HEIGHT 240 +#define UC8173_WIDTH 240 +/*------------------ Set FB parameters ------------------*/ +#define FB_REVERSEAXIS_Y UC8173_REVERSEAXIS_Y +#define FB_REVERSEAXIS_X UC8173_REVERSEAXIS_X +#define FB_WIDTH UC8173_WIDTH +#define FB_HEIGHT UC8173_HEIGHT +#define FB_PAGES 1 +#define FB_PIXELORDER_MSB TRUE + +/*------------------ Include Generic FB Code ------------------*/ +// This FB is for 1,2 or 4 bits per pixel packed along the x-axis +#define FB_TYPE_PIXELS (LLDCOLOR_TYPE_BITS/LLDCOLOR_BITS) +#define FB_AXIS_MASK (FB_TYPE_PIXELS-1) +#define FB_LINE_TYPES ((FB_WIDTH+FB_TYPE_PIXELS-1)/FB_TYPE_PIXELS) +#define FB_PAGE_TYPES (FB_LINE_TYPES*FB_HEIGHT) +#define FB_ADDR(fbp, pg, px, py) ((fbp)->fb + ((px)/FB_TYPE_PIXELS + (py)*FB_LINE_TYPES + (pg)*FB_PAGE_TYPES)) +#if FB_PIXELORDER_MSB + #define FB_COLOR(px, py, c) ((c) << ((LLDCOLOR_TYPE_BITS-LLDCOLOR_BITS)-(((px) & FB_AXIS_MASK)<<(LLDCOLOR_BITS-1)))) +#else + #define FB_COLOR(px, py, c) ((c) << (((px) & FB_AXIS_MASK)<<(LLDCOLOR_BITS-1))) +#endif +#define FB_FLUSH_REQUIRED(fbp) ((fbp)->fa0.x < (fbp)->fa1.x) +#define FB_FLUSH_WIDTH(fbp) ((fbp)->fa1.x - (fbp)->fa0.x + 1) +#define FB_FLUSH_HEIGHT(fbp) ((fbp)->fa1.y - (fbp)->fa0.y + 1) +#define FB_FLUSH_ALL(fbp) { (fbp)->fa0.x = (fbp)->fa0.y = 0; (fbp)->fa1.x = FB_WIDTH-1; (fbp)->fa1.y = FB_HEIGHT-1; } +#define FB_FLUSH_NONE(fbp) { (fbp)->fa0.x = FB_WIDTH; (fbp)->fa0.y = FB_HEIGHT; (fbp)->fa1.x = (fbp)->fa1.y = -1; } +#define FB_FLUSH_POINT(fbp, px, py) { \ + if ((px) < (fbp)->fa0.x) (fbp)->fa0.x = (px) & ~FB_AXIS_MASK; \ + if ((px) > (fbp)->fa1.x) (fbp)->fa1.x = (px) | FB_AXIS_MASK; \ + if ((py) < (fbp)->fa0.y) (fbp)->fa0.y = (py); \ + if ((py) > (fbp)->fa1.y) (fbp)->fa1.y = (py); \ + } +#define FB_SETPIXEL(fbp, pg, px, py, c) { \ + LLDCOLOR_TYPE *p, oc; \ + p = FB_ADDR((fbp), (pg), (px), (py)); \ + oc = (*p & ~FB_COLOR((px), (py), LLDCOLOR_MASK())) | FB_COLOR((px), (py), (c)); \ + if (oc != *p) { *p = oc; FB_FLUSH_POINT((fbp), (px), (py)); } \ + } + +typedef struct FBpriv { + point_t fa0, fa1; + LLDCOLOR_TYPE fb[FB_PAGE_TYPES * FB_PAGES]; + } FBpriv; + +/*------------------ UC8173 Driver Code ------------------*/ + +#include "UC8173.h" + +// UC8173 Inernal Macros & types typedef struct UC8173_Private { - coord_t flushWindowX; - coord_t flushWindowY; - coord_t flushWindowWidth; - coord_t flushWindowHeight; + UC8173Lut *lut; + FBpriv fb; } UC8173_Private; -// This function rounds a given integer up to a specified multiple. Note, multiple must be a power of 2! -static GFXINLINE void _roundUp(coord_t* numToRound, uint8_t multiple) -{ - *numToRound = (*numToRound + multiple - 1) & ~(multiple - 1); -} - -static GFXINLINE void _wait_for_busy_high(GDisplay* g) -{ - while (!getpin_busy(g)); -} - -static GFXINLINE void _wait_for_busy_low(GDisplay* g) -{ - while (getpin_busy(g)); -} - -void _load_lut(GDisplay* g, uint32_t lutRegister, const uint8_t* lut, uint32_t lutCounter) -{ - uint32_t i; - - write_cmd(g, lutRegister); - for (i = 0; i < lutCounter; i++) { - write_data(g, *lut); - lut++; - } -} - -static void _upload_lut(GDisplay* g) -{ - _load_lut(g, LUT_KWVCOM, _lut_KWvcom_DC_A2_240ms, 32); - _load_lut(g, LUT_KW, _lut_kw_A2_240ms, 512); - _load_lut(g, LUT_FT, _lut_ft, 128); -} - -static void _clear_lut(GDisplay* g) -{ - write_cmd(g, PON); - _wait_for_busy_high(g); - - _load_lut(g, LUT_KW, _lut_None, 42); - _load_lut(g, LUT_KWVCOM, _lut_None, 42); - - write_cmd(g, POF); - _wait_for_busy_low(g); -} - -#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL - static void _invertFramebuffer(GDisplay* g) - { - uint32_t i; - - for (i = 0; i < LINE_BYTES*GDISP_SCREEN_HEIGHT; i++) { - FRAMEBUFFER(g)[i] = ~(FRAMEBUFFER(g)[i]); - } - - // We should flush these changes to the display controller framebuffer at some point - g->flags |= GDISP_FLG_NEEDFLUSH; - } +#if !UC8173_INIT_REAL_LUT + static uint8_t const UC8173_LUT_None[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00 + }; #endif - + LLDSPEC bool_t gdisp_lld_init(GDisplay* g) { - // Allocate the private area plus the framebuffer - g->priv = gfxAlloc(sizeof(UC8173_Private) + LINE_BYTES*GDISP_SCREEN_HEIGHT); - if (!g->priv) { + UC8173_Private *priv; + + // Allocate the private area + g->priv = gfxAlloc(sizeof(UC8173_Private)); + if (!g->priv) return FALSE; - } + priv = (UC8173_Private *)g->priv; // Initialize the private area - PRIV(g)->flushWindowX = 0; - PRIV(g)->flushWindowY = 0; - PRIV(g)->flushWindowWidth = GDISP_SCREEN_WIDTH; - PRIV(g)->flushWindowHeight = GDISP_SCREEN_HEIGHT; + // As the display is non-volatile we need to ensure a full flush on the first draw + priv->lut = &UC8173_ModeTable[UC8173_DEFAULT_MODE]; + FB_FLUSH_ALL(&priv->fb); // Initialise the board interface - if (!init_board(g)) { + if (!init_board(g)) return FALSE; - } // Hardware reset setpin_reset(g, FALSE); gfxSleepMilliseconds(100); setpin_reset(g, TRUE); - gfxSleepMilliseconds(1000); + gfxSleepMilliseconds(300); // Acquire the bus acquire_bus(g); - // Booster soft-start + // Booster soft-start - Values from example code write_cmd(g, BTST); - write_data(g, 0x17); //0x17 - write_data(g, 0x97); //0x97 - write_data(g, 0x20); //0x20 + write_data(g, 0x17); // data: PhaseA: Bits76=StartupTime [10ms+n*10ms def=0x00], Bits543=Strength, Bits210=MinGDROffTime + write_data(g, 0x97); // data: PhaseB: Bits76=StartupTime [10ms+n*10ms def=0x00], Bits543=Strength, Bits210=MinGDROffTime + write_data(g, 0x20); // data: PhaseC: Bits543=Strength, Bits210=MinGDROffTime [def=0x07] - // Power settings + // Power settings - Values from datasheet default values write_cmd(g, PWR); - write_data(g, 0x03); - write_data(g, 0x00); - write_data(g, 0x2B); //1C 2B - write_data(g, 0x2B); //1C 2B - write_data(g, 0x00); + write_data(g, 0x03); // data: 0x02=Internal VDH/VDL, 0x01=Internal VGH/VGL + write_data(g, 0x00); // data: Always 0x00 + write_data(g, 0x26); // data: 0x00->0x3F VSH Voltage 2.4V -> 11.0V step 0.2V - default=10V (0x26) + write_data(g, 0x26); // data: 0x00->0x3F VSL Voltage 2.4V -> 11.0V step 0.2V - default=10V (0x26) + write_data(g, 0x03); // data: 0x00->0x3F Red Voltage 2.4V -> 11.0V step 0.2V - default= 3V (0x03) // Power-on write_cmd(g, PON); - _wait_for_busy_high(g); + while (!getpin_busy(g)); - // Panel setting register - write_cmd(g, PSR); - write_data(g, 0x0F); //0x0B - write_data(g, 0x86); //0x86 + // Panel setting register - Values from datasheet (OTP untested) + write_cmd(g, PSR); // data: 0x08 + ..., 0x04=Shift Right, 0x02=Booster On, 0x01=Reset Off + write_data(g, 0x0F); + #if UC8173_USE_OTP_LUT + write_cmd(g, 0x86); // data: Always 0x86, write_data=Register LUT, write_cmd=OTP LUT + #else + write_data(g, 0x86); + #endif - // Power-off sequence - write_cmd(g, PFS); + // Power-off sequence - Values from example code + write_cmd(g, PFS); // data: Shutdown frames - 0x00=1, 0x10=2, 0x20=3, 0x30=4 write_data(g, 0x00); - // PLL control - write_cmd(g, LPRD); + // PLL control - Values from example code + write_cmd(g, LPRD); // data: PLL Clock Freq = 1MHz/(n+1) Min=0x04 (=200kHz) write_data(g, 0x25); - // Internal temperature sensor enable - write_cmd(g, TSE); - write_data(g, 0x00); // Use internal temperature sensor - - // VCOM and data interval settings - write_cmd(g, CDI); - write_data(g, 0xE1); - write_data(g, 0x20); - write_data(g, 0x10); - - // Set display panel resolution - write_cmd(g, TRES); - write_data(g, 0xEF); + // Internal temperature sensor enable - Values from example code + write_cmd(g, TSE); // data: 0x00=Use internal temperature sensor, 0x80=external, Bits0-4=signed degrees to add eg 0x0F = -1 write_data(g, 0x00); - write_data(g, 0xEF); - // Undocumented register, taken from sample code + // VCOM settings - Values from datasheet + write_cmd(g, CDI); // data: 0x80=Border Hi-Z, 0x40=Border Output DC enabled, 0x30=BorderColor, 0x01=Normal/Inverted + #if UC8171_BORDER == 0 + write_data(g, 0x81); + #elif UC8171_BORDER == 1 + write_data(g, 0x41); + #elif UC8171_BORDER == 2 + write_data(g, 0x71); + #else + #error "UC8173: UC8173_BORDER must be 0..2" + #endif + + // More VCOM data - Values from example code + write_data(g, 0x20); // data: 0xX0=Src->VCOM interval (n+1 HSync, Def=0011), 0b0000-00XX=VCOM->Src interval (top 2 bits) + write_data(g, 0x10); // data: 0xXX=VCOM->Src interval (bottom 8 bits) Def=0x18 + + // Set display panel resolution - from datasheet: should always be 240x240 for this chip + write_cmd(g, TRES); + write_data(g, (UC8173_WIDTH-1)); + write_data(g, ((UC8173_HEIGHT-1)>>8)); + write_data(g, ((UC8173_HEIGHT-1) & 0xFF)); + + // Undocumented register - Values from example code write_cmd(g, GDS); write_data(g, 0xA9); write_data(g, 0xA9); @@ -198,45 +222,72 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) write_data(g, 0xEB); write_data(g, 0x02); - // Auto measure VCOM + // Auto measure VCOM - Values from example code write_cmd(g, AMV); - write_data(g, 0x11); // 5 seconds, enabled - _wait_for_busy_high(g); + write_data(g, 0x11); + while (!getpin_busy(g)); - // Get current VCOM value - // write_cmd(g, VV); - // unsigned char vcom_temp = spi_9b_get(); - // vcom_temp = vcom_temp + 4; - // Auto_VCOM = vcom_temp; - - // VCM_DC setting - write_cmd(g, VDCS); - write_data(g, 0x12); // Write vcom_temp here + // Get current VCOM value and write it + #if defined(UC8173_VCOM_VOLTAGEBYTE) + // VCM_DC setting + write_cmd(g, VDCS); + write_data(g, UC8173_VCOM_VOLTAGEBYTE); // was 0x12 in example code = -1.0V + #elif UC8173_CAN_READ + { + uint8_t vc; + + write_cmd(g, VV); + vc = read_data(g); + write_cmd(g, VDCS); + write_data(g, vc); + } + #else + #error "UC8173: Either UC8173_VCOM_VOLTAGE or UC8173_VCOM_VOLTAGEBYTE must be defined or UC8173_CAN_READ must be TRUE" + #endif - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, VBDS); write_data(g, 0x22); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, LVSEL); write_data(g, 0x02); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, GBS); write_data(g, 0x02); write_data(g, 0x02); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, GSS); write_data(g, 0x02); write_data(g, 0x02); - // Undocumented register, taken from sample code + // Undocumented register - Values from example code write_cmd(g, DF); // For REGAL (???) write_data(g, 0x1F); - // Clear the look-up table - _clear_lut(g); + write_cmd(g, PON); + while (!getpin_busy(g)); + + #if UC8173_INIT_REAL_LUT + // Load the real LUT's + write_cmd(g, LUT_KWVCOM); + write_data_burst(g, priv->lut->lutVCOM, 32); + write_cmd(g, LUT_KW); + write_data_burst(g, priv->lut->lutFW, 512); + write_cmd(g, LUT_FT); + write_data_burst(g, priv->lut->lutFT, 128); + #else + // Clear the LUT's - Values from example code + write_cmd(g, LUT_KW); + write_data_burst(g, UC8173_LUT_None, sizeof(UC8173_LUT_None)); + write_cmd(g, LUT_KWVCOM); + write_data_burst(g, UC8173_LUT_None, sizeof(UC8173_LUT_None)); + #endif + + write_cmd(g, POF); + while (getpin_busy(g)); // Finish Init post_init_board(g); @@ -245,8 +296,8 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) release_bus(g); // Initialise the GDISP structure - g->g.Width = GDISP_SCREEN_WIDTH; - g->g.Height = GDISP_SCREEN_HEIGHT; + g->g.Width = UC8173_WIDTH; + g->g.Height = UC8173_HEIGHT; g->g.Orientation = GDISP_ROTATE_0; g->g.Powermode = powerOn; g->g.Backlight = 0; @@ -258,64 +309,81 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) #if GDISP_HARDWARE_FLUSH LLDSPEC void gdisp_lld_flush(GDisplay* g) { - coord_t y; + coord_t cy, cx, dx, dy; + LLDCOLOR_TYPE *fb; + UC8173_Private *priv; - // Don't flush unless we really need to - if (!(g->flags & GDISP_FLG_NEEDFLUSH)) { + priv = (UC8173_Private *)g->priv; + + if (!FB_FLUSH_REQUIRED(&priv->fb)) return; - } - - // Round the flushing window width and height up to the next multiple of four - _roundUp(&(PRIV(g)->flushWindowWidth), 4); - _roundUp(&(PRIV(g)->flushWindowWidth), 4); + #if 0 + FB_FLUSH_ALL(&priv->fb); + #endif + // Acquire the bus to communicate with the display controller acquire_bus(g); // Upload the new temperature LUT - _upload_lut(g); + write_cmd(g, LUT_KWVCOM); + write_data_burst(g, priv->lut->lutVCOM, 32); + write_cmd(g, LUT_KW); + write_data_burst(g, priv->lut->lutFW, 512); + write_cmd(g, LUT_FT); + write_data_burst(g, priv->lut->lutFT, 128); + + // Calculate the width, height + cx = FB_FLUSH_WIDTH(&priv->fb); + cy = FB_FLUSH_HEIGHT(&priv->fb); // Setup the window + // Datasheet says x,y,w,h but in practice it needs to be x,y,w-1,h-1 write_cmd(g, DTMW); - write_data(g, (uint8_t)((PRIV(g)->flushWindowX >> 0) & 0xFF)); - write_data(g, (uint8_t)((PRIV(g)->flushWindowY >> 8) & 0x03)); - write_data(g, (uint8_t)((PRIV(g)->flushWindowY >> 0) & 0xFF)); - write_data(g, (uint8_t)((((PRIV(g)->flushWindowWidth)-1) >> 0) & 0xFF)); - write_data(g, (uint8_t)((((PRIV(g)->flushWindowHeight)-1) >> 8) & 0x03)); - write_data(g, (uint8_t)((((PRIV(g)->flushWindowHeight)-1) >> 0) & 0xFF)); + write_data(g, (uint8_t)((priv->fb.fa0.x >> 0) & 0xFF)); + write_data(g, (uint8_t)((priv->fb.fa0.y >> 8) & 0x03)); + write_data(g, (uint8_t)((priv->fb.fa0.y >> 0) & 0xFF)); + write_data(g, (uint8_t)(((cx-1) >> 0) & 0xFF)); + write_data(g, (uint8_t)(((cy-1) >> 8) & 0x03)); + write_data(g, (uint8_t)(((cy-1) >> 0) & 0xFF)); - // Dump our framebuffer - // Note: The display controller doesn't allow changing the vertical scanning direction - // so we have to manually send the lines "the other way around" here. - write_cmd(g, WRITEBUFCMD); - for (y = GDISP_SCREEN_HEIGHT-1; y >= 0; y--) { - write_data_burst(g, FRAMEBUFFER(g)+y*LINE_BYTES, LINE_BYTES); - } + // Transfer the buffer + #if GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_MONO + write_cmd(g, DTM4); + #elif GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_GRAY4 + write_cmd(g, DTM2); + #else + #error "UC8173: Unsupported driver color format" + #endif + dx = (cx+FB_TYPE_PIXELS-1)/FB_TYPE_PIXELS * (LLDCOLOR_TYPE_BITS/8); + for (fb = FB_ADDR(&priv->fb, 0, priv->fb.fa0.x, priv->fb.fa0.y), dy = cy; dy; dy--, fb += FB_LINE_TYPES) + write_data_burst(g, (uint8_t *)fb, dx); // Power-up the DC/DC converter to update the display panel write_cmd(g, PON); - _wait_for_busy_high(g); + while (!getpin_busy(g)); // Refresh the panel contents - write_cmd(g, DRF); - write_data(g, 0x00); // Enable REGAL function - write_data(g, 0x00); - write_data(g, 0x00); - write_data(g, 0x00); - write_data(g, 0xEF); - write_data(g, 0x00); - write_data(g, 0xEF); - _wait_for_busy_high(g); + // Datasheet says x,y,w,h but in practice it needs to be x,y,w-1,h-1 + write_cmd(g, DRF); // data: Partial Scan = 0x10, REGAL = 0x08, VCOM_DoNothing = 0x04 (GC4/A2 = 0x00, GU4 = 0x08) + write_data(g, (priv->lut->regal ? 0x08 : 0x00)); + write_data(g, (uint8_t)((priv->fb.fa0.x >> 0) & 0xFF)); + write_data(g, (uint8_t)((priv->fb.fa0.y >> 8) & 0x03)); + write_data(g, (uint8_t)((priv->fb.fa0.y >> 0) & 0xFF)); + write_data(g, (uint8_t)(((cx-1) >> 0) & 0xFF)); + write_data(g, (uint8_t)(((cy-1) >> 8) & 0x03)); + write_data(g, (uint8_t)(((cy-1) >> 0) & 0xFF)); + while (!getpin_busy(g)); - // Power-down the DC/DC converter to make all the low-power pussys happy + // Power-down the DC/DC converter write_cmd(g, POF); - _wait_for_busy_low(g); + while (getpin_busy(g)); - // Release the bus again + // Release the bus release_bus(g); - // Clear the 'need-flushing' flag - g->flags &=~ GDISP_FLG_NEEDFLUSH; + // Mark as flushed + FB_FLUSH_NONE(&priv->fb); } #endif @@ -323,70 +391,134 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay* g) LLDSPEC void gdisp_lld_draw_pixel(GDisplay* g) { coord_t x, y; - LLDCOLOR_TYPE *p; + UC8173_Private *priv; + + priv = (UC8173_Private *)g->priv; // Handle the different possible orientations - switch(g->g.Orientation) { - default: - case GDISP_ROTATE_0: - x = g->p.x; - y = g->p.y; - break; - case GDISP_ROTATE_90: - x = g->p.y; - y = GDISP_SCREEN_HEIGHT-1 - g->p.x; - break; - case GDISP_ROTATE_180: - x = GDISP_SCREEN_WIDTH-1 - g->p.x; - y = GDISP_SCREEN_HEIGHT-1 - g->p.y; - break; - case GDISP_ROTATE_270: - x = GDISP_SCREEN_WIDTH-1 - g->p.y; - y = g->p.x; - break; - } + #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL + switch(g->g.Orientation) { + default: + case GDISP_ROTATE_0: + #if FB_REVERSEAXIS_X + x = FB_WIDTH-1 - g->p.x; + #else + x = g->p.x; + #endif + #if FB_REVERSEAXIS_Y + y = FB_HEIGHT-1 - g->p.y; + #else + y = g->p.y; + #endif + break; + case GDISP_ROTATE_90: + #if FB_REVERSEAXIS_X + x = FB_WIDTH-1 - g->p.y; + #else + x = g->p.y; + #endif + #if FB_REVERSEAXIS_Y + y = g->p.x; + #else + y = FB_HEIGHT-1 - g->p.x; + #endif + break; + case GDISP_ROTATE_180: + #if FB_REVERSEAXIS_X + x = g->p.x; + #else + x = FB_WIDTH-1 - g->p.x; + #endif + #if FB_REVERSEAXIS_Y + y = g->p.y; + #else + y = FB_HEIGHT-1 - g->p.y; + #endif + break; + case GDISP_ROTATE_270: + #if FB_REVERSEAXIS_X + x = g->p.y; + #else + x = FB_WIDTH-1 - g->p.y; + #endif + #if FB_REVERSEAXIS_Y + y = FB_HEIGHT-1 - g->p.x; + #else + y = g->p.x; + #endif + break; + } + #else + #if FB_REVERSEAXIS_X + x = FB_WIDTH-1 - g->p.x; + #else + x = g->p.x; + #endif + #if FB_REVERSEAXIS_Y + y = FB_HEIGHT-1 - g->p.y; + #else + y = g->p.y; + #endif + #endif // Modify the framebuffer content - p = &FRAMEBUFFER(g)[xyaddr(x,y)]; - *p &=~ xybit(x, LLDCOLOR_MASK()); - *p |= xybit(x, gdispColor2Native(g->p.color)); - -// ToDo -// There appears to be an issue in the silicone, still talking to the manufacturer about this one. Update will follow! -#if 0 - // Update the flush window region - if (g->flags & GDISP_FLG_NEEDFLUSH) { - if (x < PRIV(g)->flushWindowX) - PRIV(g)->flushWindowX = x; - if (y < PRIV(g)->flushWindowY) - PRIV(g)->flushWindowY = y; - if (x > PRIV(g)->flushWindowX + PRIV(g)->flushWindowWidth) - PRIV(g)->flushWindowWidth = - } else { - PRIV(g)->flushWindowX = x; - PRIV(g)->flushWindowY = y; - PRIV(g)->flushWindowWidth = 1; - PRIV(g)->flushWindowHeight = 1; - } -#else - PRIV(g)->flushWindowX = 0; - PRIV(g)->flushWindowY = 0; - PRIV(g)->flushWindowWidth = GDISP_SCREEN_WIDTH; - PRIV(g)->flushWindowHeight = GDISP_SCREEN_HEIGHT; -#endif - - // We should flush these changes to the display controller framebuffer at some point - g->flags |= GDISP_FLG_NEEDFLUSH; + FB_SETPIXEL(&priv->fb, 0, x, y, gdispColor2Native(g->p.color)); } #endif #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL LLDSPEC void gdisp_lld_control(GDisplay* g) { + UC8173_Private *priv; + + priv = (UC8173_Private *)g->priv; + switch(g->p.x) { + + // Custom gdispControl() to invert the framebuffer case GDISP_CONTROL_INVERT: - _invertFramebuffer(g); + { + unsigned i; + LLDCOLOR_TYPE *fb; + + // Invert the framebuffer + for (fb = priv->fb.fb, i = FB_PAGE_TYPES; i ; i--, fb++) + fb[0] = ~fb[0]; + + // We should flush these changes to the display controller framebuffer at some point + FB_FLUSH_ALL(&priv->fb); + } break; + // Custom gdispControl() to set which EINK Mode (waveform) to use + case GDISP_CONTROL_SETMODE: + if ((unsigned)g->p.ptr < sizeof(UC8173_ModeTable)/sizeof(UC8173_ModeTable[0])) + priv->lut = &UC8173_ModeTable[(unsigned)g->p.ptr]; + break; + + // Custom gdispControl() to set the EINK border + case GDISP_CONTROL_SETBORDER: + if ((unsigned)g->p.ptr > 2) + break; + acquire_bus(g); + write_cmd(g, PON); + while (!getpin_busy(g)); + write_cmd(g, CDI); + switch((unsigned)g->p.ptr) { + case 0: + write_data(g, 0x81); // Border Hi-Z + break; + case 1: + write_data(g, 0x41); // Border Black + break; + case 2: + write_data(g, 0x71); // Border White + break; + } + write_cmd(g, POF); + while (getpin_busy(g)); + release_bus(g); + break; + default: break; } diff --git a/drivers/gdisp/UC8173/gdisp_lld_config.h b/drivers/gdisp/UC8173/gdisp_lld_config.h index e10928eb..1d9146a2 100644 --- a/drivers/gdisp/UC8173/gdisp_lld_config.h +++ b/drivers/gdisp/UC8173/gdisp_lld_config.h @@ -16,13 +16,16 @@ #define GDISP_HARDWARE_FLUSH TRUE #define GDISP_HARDWARE_DRAWPIXEL TRUE -#define GDISP_HARDWARE_PIXELREAD FALSE +//#define GDISP_HARDWARE_PIXELREAD TRUE - not implemented yet #define GDISP_HARDWARE_CONTROL TRUE #define GDISP_HARDWARE_FILLS FALSE #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO +//#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY4 #define GDISP_CONTROL_INVERT (GDISP_CONTROL_LLD+0) +#define GDISP_CONTROL_SETMODE (GDISP_CONTROL_LLD+1) /* Parameter: 0..n (as defined by the board file) */ +#define GDISP_CONTROL_SETBORDER (GDISP_CONTROL_LLD+2) /* Parameter: 0=Border Hi-Z, 1=Border Black, 2=Border White */ #endif /* GFX_USE_GDISP */