7 changed files with 852 additions and 0 deletions
@ -0,0 +1,121 @@ |
|||
#ifndef _GDISP_LLD_BOARD_H |
|||
#define _GDISP_LLD_BOARD_H |
|||
|
|||
#include "nrf_gpio.h" |
|||
#include "nrf_drv_spi.h" |
|||
#include "app_util_platform.h" |
|||
|
|||
#define PIN_CS 29 |
|||
#define PIN_SCK 3 |
|||
#define PIN_MOSI 4 |
|||
#define PIN_DC 12 |
|||
#define PIN_RESET 11 |
|||
#define PIN_BUSY 27 |
|||
|
|||
#define SPI_INSTANCE 0 |
|||
|
|||
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); |
|||
|
|||
static GFXINLINE bool_t init_board(GDisplay* g) |
|||
{ |
|||
nrf_drv_spi_config_t spi_config; |
|||
ret_code_t err = NRF_SUCCESS; |
|||
|
|||
(void)g; |
|||
|
|||
// Initialize RESET pin
|
|||
nrf_gpio_cfg_output(PIN_RESET); |
|||
|
|||
// Initialize RESET pin
|
|||
nrf_gpio_cfg_output(PIN_DC); |
|||
|
|||
// Initialize BUSY pin
|
|||
nrf_gpio_cfg_input(PIN_BUSY, NRF_GPIO_PIN_NOPULL); |
|||
|
|||
// Initialize RESET pin
|
|||
nrf_gpio_cfg_output(PIN_CS); |
|||
|
|||
// Initialize SPI
|
|||
spi_config.sck_pin = PIN_SCK; |
|||
spi_config.mosi_pin = PIN_MOSI; |
|||
spi_config.miso_pin = NRF_DRV_SPI_PIN_NOT_USED; |
|||
spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED; // We have to control the CS line ourself for burst writes > 255 bytes
|
|||
spi_config.irq_priority = APP_IRQ_PRIORITY_LOW; |
|||
spi_config.orc = 0xFF; |
|||
spi_config.frequency = NRF_DRV_SPI_FREQ_4M; |
|||
spi_config.mode = NRF_DRV_SPI_MODE_0; |
|||
spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST; |
|||
err = nrf_drv_spi_init(&spi, &spi_config, 0); |
|||
if (err != NRF_SUCCESS) { |
|||
return FALSE; |
|||
} |
|||
|
|||
return TRUE; |
|||
} |
|||
|
|||
static GFXINLINE void post_init_board(GDisplay* g) |
|||
{ |
|||
(void)g; |
|||
} |
|||
|
|||
static GFXINLINE void setpin_reset(GDisplay* g, bool_t state) |
|||
{ |
|||
(void)g; |
|||
|
|||
if (state) { |
|||
nrf_gpio_pin_set(PIN_RESET); |
|||
} else { |
|||
nrf_gpio_pin_clear(PIN_RESET); |
|||
} |
|||
} |
|||
|
|||
static GFXINLINE bool_t getpin_busy(GDisplay* g) |
|||
{ |
|||
(void)g; |
|||
|
|||
if (nrf_gpio_pin_read(PIN_BUSY) == 1) { |
|||
return TRUE; |
|||
} else { |
|||
return FALSE; |
|||
} |
|||
} |
|||
|
|||
static GFXINLINE void acquire_bus(GDisplay* g) |
|||
{ |
|||
(void)g; |
|||
|
|||
nrf_gpio_pin_clear(PIN_CS); |
|||
} |
|||
|
|||
static GFXINLINE void release_bus(GDisplay* g) |
|||
{ |
|||
(void)g; |
|||
|
|||
nrf_gpio_pin_set(PIN_CS); |
|||
} |
|||
|
|||
static GFXINLINE void write_cmd(GDisplay* g, uint8_t cmd) |
|||
{ |
|||
(void)g; |
|||
|
|||
nrf_gpio_pin_clear(PIN_DC); |
|||
nrf_drv_spi_transfer(&spi, &cmd, 1, 0, 0); |
|||
} |
|||
|
|||
static GFXINLINE void write_data(GDisplay* g, uint8_t data) |
|||
{ |
|||
(void)g; |
|||
|
|||
nrf_gpio_pin_set(PIN_DC); |
|||
nrf_drv_spi_transfer(&spi, &data, 1, 0, 0); |
|||
} |
|||
|
|||
static GFXINLINE void write_data_burst(GDisplay* g, uint8_t* data, uint8_t length) |
|||
{ |
|||
(void)g; |
|||
|
|||
nrf_gpio_pin_set(PIN_DC); |
|||
nrf_drv_spi_transfer(&spi, data, length, 0, 0); |
|||
} |
|||
|
|||
#endif /* _GDISP_LLD_BOARD_H */ |
@ -0,0 +1,224 @@ |
|||
#ifndef _UC8173_H |
|||
#define _UC8173_H |
|||
|
|||
#include "gfx.h" |
|||
|
|||
#define DATA_MASK 0x0100 |
|||
#define DCX_CMD 0x0000 |
|||
#define DCX_DATA 0x0001 |
|||
#define MASTER 0x00 |
|||
#define SLAVE 0x01 |
|||
#define MAS_SLA 0x02 |
|||
#define BLACK 0x00 |
|||
#define WHITE 0x01 |
|||
#define RED 0x02 |
|||
|
|||
#define PSR 0x0000 |
|||
#define PWR 0x0001 |
|||
#define POF 0x0002 |
|||
#define PFS 0x0003 |
|||
#define PON 0x0004 |
|||
#define PMES 0x0005 |
|||
#define BTST 0x0006 |
|||
#define DSLP 0x0007 |
|||
#define SLP 0x0008 |
|||
#define DTM1 0x0010 |
|||
#define DRF 0x0012 |
|||
#define DTM2 0x0013 |
|||
#define DTMW 0x0014 |
|||
#define DTM3 0x0015 |
|||
#define DTM4 0x0016 |
|||
#define LUT_KWVCOM 0x0020 |
|||
#define LUT_RVCOM 0x0021 |
|||
#define LUT_KW 0x0022 |
|||
#define LUT_RR 0x0023 |
|||
#define LUT_RK 0x0024 |
|||
#define LUT_RW 0x0025 |
|||
#define LUT_FT 0x0026 |
|||
#define LPRD 0x0030 |
|||
#define TSC 0x0040 |
|||
#define TSE 0x0041 |
|||
#define TSW 0x0042 |
|||
#define TSR 0x0043 |
|||
#define PBC 0x0044 |
|||
#define CDI 0x0050 |
|||
#define LPD 0x0051 |
|||
#define TRES 0x0061 |
|||
#define GDS 0x0062 |
|||
#define GBS 0x0063 |
|||
#define GSS 0x0064 |
|||
#define REV 0x0070 |
|||
#define FLG 0x0071 |
|||
#define AMV 0x0080 |
|||
#define VV 0x0081 |
|||
#define VDCS 0x0082 |
|||
#define EDS 0x0083 |
|||
#define VBDS 0x0084 |
|||
|
|||
#define PGM 0x00A0 |
|||
#define APG 0x00A1 |
|||
#define ROTP 0x00A2 |
|||
#define CCSET 0x00E0 |
|||
#define PWS 0x00E3 |
|||
#define LVSEL 0x00E4 |
|||
#define TSSET 0x00E5 |
|||
|
|||
#define DF 0x00DF |
|||
|
|||
#define Initial_23_16 0x00 |
|||
#define Initial_15_0 0x0000 // 1K
|
|||
#define Temperature 0x001000 |
|||
#define Temperature0_23_16 0x00 |
|||
#define Temperature0_15_0 0x0400 // 1K
|
|||
#define Temperature1_23_16 0x00 |
|||
#define Temperature1_15_0 0x0800 |
|||
#define Temperature2_23_16 0x00 |
|||
#define Temperature2_15_0 0x0C00 |
|||
#define Temperature3_23_16 0x00 |
|||
#define Temperature3_15_0 0x1000 |
|||
#define Temperature4_23_16 0x00 |
|||
#define Temperature4_15_0 0x1400 |
|||
#define Temperature5_23_16 0x00 |
|||
#define Temperature5_15_0 0x1800 |
|||
#define Temperature6_23_16 0x00 |
|||
#define Temperature6_15_0 0x1C00 |
|||
#define Temperature7_23_16 0x00 |
|||
#define Temperature7_15_0 0x2000 |
|||
#define Temperature8_23_16 0x00 |
|||
#define Temperature8_15_0 0x2400 |
|||
#define Temperature9_23_16 0x00 |
|||
#define Temperature9_15_0 0x2800 |
|||
#define Temperature10_23_16 0x00 |
|||
#define Temperature10_15_0 0x2C00 |
|||
|
|||
#define Image_Start 0x003000 |
|||
|
|||
#define Initial_Counter 64 |
|||
#define Temperature_LUT_Counter 672 |
|||
|
|||
static uint8_t _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 _lut_temperature[] = { |
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
|||
0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, |
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
|||
0x00, 0x00, 0x29, 0xa9, 0xa9, 0xa8, |
|||
0x29, 0xa9, 0xa9, 0xa8, 0x29, 0xa9, |
|||
0xa9, 0xa8, 0x29, 0xa9, 0xa9, 0xa8, |
|||
0x29, 0xa9, 0xa9, 0xa8, 0x29, 0xa9, |
|||
0xa9, 0xa8, 0x29, 0xa9, 0xa9, 0xa0, |
|||
0x29, 0xa9, 0x29, 0xa0, 0x28, 0xa9, |
|||
0x21, 0x80, 0x28, 0xa9, 0x05, 0x80, |
|||
0x28, 0xa1, 0x05, 0x04, 0x28, 0x80, |
|||
0x05, 0x14, 0x08, 0x00, 0x15, 0x54, |
|||
0x00, 0x04, 0x04, 0x54, 0x02, 0x54, |
|||
0x14, 0x54, 0x02, 0x56, 0x14, 0x54, |
|||
0x06, 0x56, 0x56, 0x54, 0x06, 0x56, |
|||
0x56, 0x54, 0x16, 0x56, 0x56, 0x54, |
|||
0x16, 0x56, 0x56, 0x54, 0x16, 0x56, |
|||
0x52, 0x50, 0x16, 0x56, 0x52, 0x50, |
|||
0x16, 0x56, 0x52, 0x50, 0x16, 0x52, |
|||
0x52, 0x50, 0x16, 0x52, 0x52, 0x50, |
|||
0x12, 0x52, 0x52, 0x40, 0x12, 0x52, |
|||
0x52, 0x40, 0x1a, 0x4a, 0x4a, 0x48, |
|||
0x2a, 0x6a, 0x6a, 0x68, 0x2a, 0x6a, |
|||
0x6a, 0x68, 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, 0x50, 0x55, |
|||
0x5a, 0x55, 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, |
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
|||
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
|
@ -0,0 +1,56 @@ |
|||
/*
|
|||
* This file is subject to the terms of the GFX License. If a copy of |
|||
* the license was not distributed with this file, you can obtain one at: |
|||
* |
|||
* http://ugfx.org/license.html
|
|||
*/ |
|||
|
|||
#ifndef _GDISP_LLD_BOARD_H |
|||
#define _GDISP_LLD_BOARD_H |
|||
|
|||
static GFXINLINE void init_board(GDisplay* g) |
|||
{ |
|||
(void) g; |
|||
} |
|||
|
|||
static GFXINLINE void post_init_board(GDisplay* g) |
|||
{ |
|||
(void) g; |
|||
} |
|||
|
|||
static GFXINLINE void setpin_reset(GDisplay* g, bool_t state) |
|||
{ |
|||
(void) g; |
|||
(void) state; |
|||
} |
|||
|
|||
static GFXINLINE void acquire_bus(GDisplay* g) |
|||
{ |
|||
(void) g; |
|||
} |
|||
|
|||
static GFXINLINE void release_bus(GDisplay* g) |
|||
{ |
|||
(void) g; |
|||
} |
|||
|
|||
static GFXINLINE void write_cmd(GDisplay* g, uint8_t cmd) |
|||
{ |
|||
(void) g; |
|||
(void) cmd; |
|||
} |
|||
|
|||
static GFXINLINE void write_data(GDisplay* g, uint8_t data) |
|||
{ |
|||
(void) g; |
|||
(void) data; |
|||
} |
|||
|
|||
static GFXINLINE void write_data_burst(GDisplay* g, uint8_t* data, uint16_t length) |
|||
{ |
|||
(void) g; |
|||
(void) data; |
|||
(void) length; |
|||
} |
|||
|
|||
#endif /* _GDISP_LLD_BOARD_H */ |
@ -0,0 +1,2 @@ |
|||
GFXINC += $(GFXLIB)/drivers/gdisp/UC8173 |
|||
GFXSRC += $(GFXLIB)/drivers/gdisp/UC8173/gdisp_lld_UC8173.c |
@ -0,0 +1,419 @@ |
|||
/*
|
|||
* This file is subject to the terms of the GFX License. If a copy of |
|||
* the license was not distributed with this file, you can obtain one at: |
|||
* |
|||
* http://ugfx.org/license.html
|
|||
*/ |
|||
|
|||
#include "gfx.h" |
|||
|
|||
#if GFX_USE_GDISP |
|||
|
|||
#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_WIDTH) |
|||
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored." |
|||
#define GDISP_SCREEN_WIDTH 240 |
|||
#endif |
|||
#if defined(GDISP_SCREEN_HEIGHT) |
|||
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored." |
|||
#define GDISP_SCREEN_HEIGHT 240 |
|||
#endif |
|||
|
|||
#ifndef GDISP_SCREEN_HEIGHT |
|||
#define GDISP_SCREEN_HEIGHT 240 |
|||
#endif |
|||
#ifndef GDISP_SCREEN_WIDTH |
|||
#define GDISP_SCREEN_WIDTH 240 |
|||
#endif |
|||
|
|||
#define PRIV(g) ((UC8173_Private*)((g)->priv)) |
|||
#define FRAMEBUFFER(g) (PRIV(g)->framebuffer) |
|||
#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0) |
|||
|
|||
#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" |
|||
#endif |
|||
|
|||
typedef struct UC8173_Private { |
|||
coord_t flushWindowX; |
|||
coord_t flushWindowY; |
|||
coord_t flushWindowWidth; |
|||
coord_t flushWindowHeight; |
|||
uint8_t* framebuffer; |
|||
} 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)); |
|||
} |
|||
|
|||
static void _load_lut(GDisplay* g, uint32_t LUT, uint8_t* LUT_Value) |
|||
{ |
|||
int i,counter; |
|||
int MODE = 2; |
|||
|
|||
if(MODE == 0) |
|||
counter = 512; //512
|
|||
else |
|||
counter = 42; |
|||
if(LUT == 0x26) |
|||
counter = 128; |
|||
|
|||
write_cmd(g, LUT); |
|||
for(i = 0; i < counter; i++) { |
|||
write_data(g, *LUT_Value); |
|||
LUT_Value++; |
|||
} |
|||
} |
|||
|
|||
void _load_lut2(GDisplay* g, uint32_t LUT, uint8_t* LUT_Value, uint32_t LUT_Counter) |
|||
{ |
|||
uint32_t i; |
|||
|
|||
write_cmd(g, LUT); |
|||
for (i = 0; i < LUT_Counter; i++) { |
|||
write_data(g, *LUT_Value); |
|||
LUT_Value++; |
|||
} |
|||
} |
|||
|
|||
static void _upload_Temperature_LUT(GDisplay* g) |
|||
{ |
|||
_load_lut2(g, LUT_KWVCOM, &_lut_temperature[0], 32); |
|||
_load_lut2(g, LUT_KW, &_lut_temperature[32], 512); |
|||
_load_lut2(g, LUT_FT, &_lut_temperature[544], 128); |
|||
} |
|||
|
|||
static void _clear_lut(GDisplay* g) |
|||
{ |
|||
write_cmd(g, PON); |
|||
_wait_for_busy_high(g); |
|||
|
|||
_load_lut(g, LUT_KW, _lut_none); |
|||
_load_lut(g, LUT_KWVCOM, _lut_none); |
|||
|
|||
write_cmd(g, POF); |
|||
_wait_for_busy_low(g); |
|||
} |
|||
|
|||
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; |
|||
} |
|||
|
|||
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) { |
|||
return FALSE; |
|||
} |
|||
|
|||
// Initialize the private area
|
|||
PRIV(g)->flushWindowX = 0; |
|||
PRIV(g)->flushWindowY = 0; |
|||
PRIV(g)->flushWindowWidth = GDISP_SCREEN_WIDTH; |
|||
PRIV(g)->flushWindowHeight = GDISP_SCREEN_HEIGHT; |
|||
PRIV(g)->framebuffer = (uint8_t*)(PRIV(g) + offsetof(UC8173_Private, framebuffer)); |
|||
|
|||
// Initialise the board interface
|
|||
if (!init_board(g)) { |
|||
return FALSE; |
|||
} |
|||
|
|||
// Hardware reset
|
|||
setpin_reset(g, FALSE); |
|||
gfxSleepMilliseconds(100); |
|||
setpin_reset(g, TRUE); |
|||
gfxSleepMilliseconds(1000); |
|||
|
|||
// Acquire the bus
|
|||
acquire_bus(g); |
|||
|
|||
// Booster soft-start
|
|||
write_cmd(g, BTST); |
|||
write_data(g, 0x17); //0x17
|
|||
write_data(g, 0x97); //0x97
|
|||
write_data(g, 0x20); //0x20
|
|||
|
|||
// Power settings
|
|||
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); |
|||
|
|||
// Power-on
|
|||
write_cmd(g, PON); |
|||
_wait_for_busy_high(g); |
|||
|
|||
// Panel setting register
|
|||
write_cmd(g, PSR); |
|||
write_data(g, 0x0F); //0x0B
|
|||
write_data(g, 0x86); //0x86
|
|||
|
|||
// Power-off sequence
|
|||
write_cmd(g, PFS); |
|||
write_data(g, 0x00); |
|||
|
|||
// PLL control
|
|||
write_cmd(g, LPRD); |
|||
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); |
|||
write_data(g, 0x00); |
|||
write_data(g, 0xEF); |
|||
|
|||
// Undocumented register, taken from sample code
|
|||
write_cmd(g, GDS); |
|||
write_data(g, 0xA9); |
|||
write_data(g, 0xA9); |
|||
write_data(g, 0xEB); |
|||
write_data(g, 0xEB); |
|||
write_data(g, 0x02); |
|||
|
|||
// Auto measure VCOM
|
|||
write_cmd(g, AMV); |
|||
write_data(g, 0x11); // 5 seconds, enabled
|
|||
|
|||
_wait_for_busy_high(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
|
|||
|
|||
// Undocumented register, taken from sample code
|
|||
write_cmd(g, VBDS); |
|||
write_data(g, 0x22); |
|||
|
|||
// Undocumented register, taken from sample code
|
|||
write_cmd(g, LVSEL); |
|||
write_data(g, 0x02); |
|||
|
|||
// Undocumented register, taken from sample code
|
|||
write_cmd(g, GBS); |
|||
write_data(g, 0x02); |
|||
write_data(g, 0x02); |
|||
|
|||
// Undocumented register, taken from sample code
|
|||
write_cmd(g, GSS); |
|||
write_data(g, 0x02); |
|||
write_data(g, 0x02); |
|||
|
|||
// Undocumented register, taken from sample code
|
|||
write_cmd(g, DF); // For REGAL (???)
|
|||
write_data(g, 0x1F); |
|||
|
|||
// Clear the look-up table
|
|||
_clear_lut(g); |
|||
|
|||
// Finish Init
|
|||
post_init_board(g); |
|||
|
|||
// Release the bus
|
|||
release_bus(g); |
|||
|
|||
// Initialise the GDISP structure
|
|||
g->g.Width = GDISP_SCREEN_WIDTH; |
|||
g->g.Height = GDISP_SCREEN_HEIGHT; |
|||
g->g.Orientation = GDISP_ROTATE_0; |
|||
g->g.Powermode = powerOn; |
|||
g->g.Backlight = 0; |
|||
g->g.Contrast = 0; |
|||
|
|||
return TRUE; |
|||
} |
|||
|
|||
#if GDISP_HARDWARE_FLUSH |
|||
LLDSPEC void gdisp_lld_flush(GDisplay* g) |
|||
{ |
|||
coord_t y; |
|||
|
|||
// Don't flush unless we really need to
|
|||
if (!(g->flags & GDISP_FLG_NEEDFLUSH)) { |
|||
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); |
|||
|
|||
// Acquire the bus to communicate with the display controller
|
|||
acquire_bus(g); |
|||
|
|||
// Upload the new temperature LUT
|
|||
_upload_Temperature_LUT(g); |
|||
|
|||
// Setup the window
|
|||
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)); |
|||
|
|||
// 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); |
|||
} |
|||
|
|||
// Power-up the DC/DC converter to update the display panel
|
|||
write_cmd(g, PON); |
|||
_wait_for_busy_high(g); |
|||
|
|||
// Refresh the panel contents
|
|||
write_cmd(g, DRF); |
|||
write_data(g, 0x08); // 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); |
|||
|
|||
// Power-down the DC/DC converter to make all the low-power pussys happy
|
|||
write_cmd(g, POF); |
|||
_wait_for_busy_low(g); |
|||
|
|||
// Release the bus again
|
|||
release_bus(g); |
|||
|
|||
// Clear the 'need-flushing' flag
|
|||
g->flags &=~ GDISP_FLG_NEEDFLUSH; |
|||
} |
|||
#endif |
|||
|
|||
#if GDISP_HARDWARE_DRAWPIXEL |
|||
LLDSPEC void gdisp_lld_draw_pixel(GDisplay* g) |
|||
{ |
|||
coord_t x, y; |
|||
LLDCOLOR_TYPE *p; |
|||
|
|||
// 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; |
|||
} |
|||
|
|||
// Modify the framebuffer content
|
|||
p = &FRAMEBUFFER(g)[xyaddr(x,y)]; |
|||
*p &=~ xybit(x, LLDCOLOR_MASK()); |
|||
*p |= xybit(x, gdispColor2Native(g->p.color)); |
|||
|
|||
//#warning 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; |
|||
} |
|||
#endif |
|||
|
|||
#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL |
|||
LLDSPEC void gdisp_lld_control(GDisplay* g) { |
|||
switch(g->p.x) { |
|||
case GDISP_CONTROL_INVERT: |
|||
_invertFramebuffer(g); |
|||
break; |
|||
|
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
#endif |
|||
|
|||
#endif // GFX_USE_GDISP
|
@ -0,0 +1,29 @@ |
|||
/*
|
|||
* This file is subject to the terms of the GFX License. If a copy of |
|||
* the license was not distributed with this file, you can obtain one at: |
|||
* |
|||
* http://ugfx.org/license.html
|
|||
*/ |
|||
|
|||
#ifndef _GDISP_LLD_CONFIG_H |
|||
#define _GDISP_LLD_CONFIG_H |
|||
|
|||
#if GFX_USE_GDISP |
|||
|
|||
/*===========================================================================*/ |
|||
/* Driver hardware support. */ |
|||
/*===========================================================================*/ |
|||
|
|||
#define GDISP_HARDWARE_FLUSH TRUE |
|||
#define GDISP_HARDWARE_DRAWPIXEL TRUE |
|||
#define GDISP_HARDWARE_PIXELREAD FALSE |
|||
#define GDISP_HARDWARE_CONTROL TRUE |
|||
#define GDISP_HARDWARE_FILLS FALSE |
|||
|
|||
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO |
|||
|
|||
#define GDISP_CONTROL_INVERT (GDISP_CONTROL_LLD+0) |
|||
|
|||
#endif /* GFX_USE_GDISP */ |
|||
|
|||
#endif /* _GDISP_LLD_CONFIG_H */ |
Loading…
Reference in new issue