Added HX8347D driver by the user Eddie

ugfx_release_2.6
Joel Bodenmann 2013-05-21 00:13:22 +02:00
parent 8d5fa39dd9
commit 86951a8b2f
7 changed files with 909 additions and 0 deletions

View File

@ -0,0 +1,143 @@
/*
* This file is subject to the terms of the GFX License, v1.0. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://chibios-gfx.com/license.html
*/
/**
* @file drivers/gdisp/HX8347D/HX8347D.h
* @brief GDISP Graphic Driver support header for the HX8347D display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _HX8347D_H
#define _HX8347D_H
/* HX8347D registers */
/* page 0 registers */
#define HX8347D_REG_HID 0x00 /* Himax ID */
#define HX8347D_REG_DMODE 0x01 /* Display mode control */
#define HX8347D_REG_SCH 0x02 /* Column address start high */
#define HX8347D_REG_SCL 0x03 /* Column address start low */
#define HX8347D_REG_ECH 0x04 /* Column address end high */
#define HX8347D_REG_ECL 0x05 /* Column address end low */
#define HX8347D_REG_SPH 0x06 /* Row address start high */
#define HX8347D_REG_SPL 0x07 /* Row address start low */
#define HX8347D_REG_EPH 0x08 /* Row address end high */
#define HX8347D_REG_EPL 0x09 /* Row address end low */
#define HX8347D_REG_PSLH 0x0a /* Partial area start row high */
#define HX8347D_REG_PSLL 0x0b /* Partial area start row low */
#define HX8347D_REG_PELH 0x0c /* Partial area end row high */
#define HX8347D_REG_PELL 0x0d /* Partial area end row low */
#define HX8347D_REG_TFAH 0x0e /* Vertical srcoll top fixed area high */
#define HX8347D_REG_TFAL 0x0f /* Vertical scroll top fixed area low */
#define HX8347D_REG_VSAH 0x10 /* Vertical scroll height area high */
#define HX8347D_REG_VSAL 0x11 /* Vertical scroll height area low */
#define HX8347D_REG_BFAH 0x12 /* Vertical scroll button area high */
#define HX8347D_REG_BFAL 0x13 /* Vertical scroll button area low */
#define HX8347D_REG_VSPH 0x14 /* Vertical scroll start address high */
#define HX8347D_REG_VSPL 0x15 /* Vertical scroll start address low */
#define HX8347D_REG_MAC 0x16 /* Memory access control */
#define HX8347D_REG_COLMOD 0x17 /* COLMOD */
#define HX8347D_REG_OSCCH 0x18 /* OSC control 2 */
#define HX8347D_REG_OSCCL 0x19 /* OSC control 1 */
#define HX8347D_REG_PWC1 0x1a /* Power control 1 */
#define HX8347D_REG_PWC2 0x1b /* Power control 2 */
#define HX8347D_REG_PWC3 0x1c /* Power control 3 */
#define HX8347D_REG_PWC4 0x1d /* Power control 4 */
#define HX8347D_REG_PWC5 0x1e /* Power control 5 */
#define HX8347D_REG_PWC6 0x1f /* Power control 6 */
#define HX8347D_REG_SRAMWC 0x22 /* SRAM write control */
#define HX8347D_REG_VMF 0x23 /* VCOM control 1 */
#define HX8347D_REG_VMH 0x24 /* VCOM control 2 */
#define HX8347D_REG_VML 0x25 /* VCOM control 3 */
#define HX8347D_REG_DC1 0x26 /* Display control 1 */
#define HX8347D_REG_DC2 0x27 /* Display control 2 */
#define HX8347D_REG_DC3 0x28 /* Display control 3 */
#define HX8347D_REG_FRC1 0x29 /* Frame rate control 1 */
#define HX8347D_REG_FRC2 0x2a /* Frame rate control 2 */
#define HX8347D_REG_FRC3 0x2b /* Frame rate control 3 */
#define HX8347D_REG_FRC4 0x2c /* Frame rate control 4 */
#define HX8347D_REG_GDON 0x2d /* Cycle control 1 */
#define HX8347D_REG_GDOF 0x2e /* Cycle control 2 */
#define HX8347D_REG_DINV 0x2f /* Display inversion */
#define HX8347D_REG_RGB1 0x31 /* RGB interface control 1 */
#define HX8347D_REG_RGB2 0x32 /* RGB interface control 2 */
#define HX8347D_REG_RGB3 0x33 /* RGB interface control 3 */
#define HX8347D_REG_RGB4 0x34 /* RGB interface control 4 */
#define HX8347D_REG_PCH 0x36 /* Panel characteristic */
#define HX8347D_REG_OTP1 0x38 /* OTP control 1 */
#define HX8347D_REG_OTP2 0x39 /* OTP control 2 */
#define HX8347D_REG_OTP3 0x3a /* OTP control 3 */
#define HX8347D_REG_CABC1 0x3c /* CABC control 1 */
#define HX8347D_REG_CABC2 0x3d /* CABC control 2 */
#define HX8347D_REG_CABC3 0x3e /* CABC control 3 */
#define HX8347D_REG_CABC4 0x3f /* CABC control 4 */
#define HX8347D_REG_VRP0 0x40 /* Gamma control 1 */
#define HX8347D_REG_VRP1 0x41 /* Gamma control 2 */
#define HX8347D_REG_VRP2 0x42 /* Gamma control 3 */
#define HX8347D_REG_VRP3 0x43 /* Gamma control 4 */
#define HX8347D_REG_VRP4 0x44 /* Gamma control 5 */
#define HX8347D_REG_VRP5 0x45 /* Gamma control 6 */
#define HX8347D_REG_PRP0 0x46 /* Gamma control 7 */
#define HX8347D_REG_PRP1 0x47 /* Gamma control 8 */
#define HX8347D_REG_PKP0 0x48 /* Gamma control 9 */
#define HX8347D_REG_PKP1 0x49 /* Gamma control 10 */
#define HX8347D_REG_PKP2 0x4a /* Gamma control 11 */
#define HX8347D_REG_PKP3 0x4b /* Gamma control 12 */
#define HX8347D_REG_PKP4 0x4c /* Gamma control 13 */
#define HX8347D_REG_VRN0 0x50 /* Gamma control 14 */
#define HX8347D_REG_VRN1 0x51 /* Gamma control 15 */
#define HX8347D_REG_VRN2 0x52 /* Gamma control 16 */
#define HX8347D_REG_VRN3 0x53 /* Gamma control 17 */
#define HX8347D_REG_VRN4 0x54 /* Gamma control 18 */
#define HX8347D_REG_VRN5 0x55 /* Gamma control 19 */
#define HX8347D_REG_PRN0 0x56 /* Gamma control 20 */
#define HX8347D_REG_PRN1 0x57 /* Gamma control 21 */
#define HX8347D_REG_PKN0 0x58 /* Gamma control 22 */
#define HX8347D_REG_PKN1 0x59 /* Gamma control 23 */
#define HX8347D_REG_PKN2 0x5a /* Gamma control 24 */
#define HX8347D_REG_PKN3 0x5b /* Gamma control 25 */
#define HX8347D_REG_PKN4 0x5c /* Gamma control 26 */
#define HX8347D_REG_CGM 0x5d /* Gamma control 27 */
#define HX8347D_REG_TEC 0x60 /* TE control */
#define HX8347D_REG_PS1 0xe4 /* Power saving 1 */
#define HX8347D_REG_PS2 0xe5 /* Power saving 2 */
#define HX8347D_REG_PS3 0xe6 /* Power saving 3 */
#define HX8347D_REG_PS4 0xe7 /* Power saving 4 */
#define HX8347D_REG_OPONN 0xe8 /* Source OP control normal */
#define HX8347D_REG_OPONI 0xe9 /* Source OP control idle */
#define HX8347D_REG_STBAH 0xea /* Power control internal use 1 */
#define HX8347D_REG_STBAL 0xeb /* Power control internal use 2 */
#define HX8347D_REG_PTBAH 0xec /* Source control internal use 1 */
#define HX8347D_REG_PTBAL 0xed /* Source control internal use 2 */
/* page 1 registers */
#define HX8347D_REG_CABC5 0xc3 /* CABC control 5 */
#define HX8347D_REG_CABC6 0xc5 /* CABC control 6 */
#define HX8347D_REG_CABC7 0xc7 /* CABC control 7 */
#define HX8347D_REG_DBG0 0xcb /* Gain select register 0 */
#define HX8347D_REG_DBG1 0xcc /* Gain select register 1 */
#define HX8347D_REG_DBG2 0xcd /* Gain select register 2 */
#define HX8347D_REG_DBG3 0xce /* Gain select register 3 */
#define HX8347D_REG_DBG4 0xcf /* Gain select register 4 */
#define HX8347D_REG_DBG5 0xd0 /* Gain select register 5 */
#define HX8347D_REG_DBG6 0xd1 /* Gain select register 6 */
#define HX8347D_REG_DBG7 0xd2 /* Gain select register 7 */
#define HX8347D_REG_DBG8 0xd3 /* Gain select register 8 */
#define HX8347D_REG_PGSEL 0xff /* Page select */
#endif /* _HX8347D_H */
/** @} */

View File

@ -0,0 +1,495 @@
/*
* This file is subject to the terms of the GFX License, v1.0. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://chibios-gfx.com/license.html
*/
/**
* @file drivers/gdisp/HX8347D/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for the HX8347D display.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#include "HX8347D.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#ifndef GDISP_SCREEN_HEIGHT
#define GDISP_SCREEN_HEIGHT 320
#endif
#ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 240
#endif
#define GDISP_INITIAL_CONTRAST 50
#define GDISP_INITIAL_BACKLIGHT 50
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif defined(BOARD_ST_STM32F4_DISCOVERY)
#include "gdisp_lld_board_st_stm32f4_discovery.h"
#else
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#endif
// Some common routines and macros
#define write_reg(reg, data) { write_index(reg); write_data(data); }
#define write_ram(color1, color2) { write_index(0x22); write_ram8(color1,color2); }
#define stream_start() { write_index(0x22); spiStart(&SPID1, &spi1cfg2); }
#define stream_stop() {while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));palSetPad(GPIOA, 4);spiStart(&SPID1, &spi1cfg1); }
#define delay(us) chThdSleepMicroseconds(us)
#define delayms(ms) chThdSleepMilliseconds(ms)
static inline void set_cursor(coord_t x, coord_t y) {
write_reg(HX8347D_REG_SCL, (uint8_t) x);
write_reg(HX8347D_REG_SCH, (uint8_t) (x >> 8));
write_reg(HX8347D_REG_SPL, (uint8_t) y);
write_reg(HX8347D_REG_SPH, (uint8_t) (y >> 8));
}
static void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
write_reg(HX8347D_REG_SCL, (uint8_t) x);
write_reg(HX8347D_REG_SCH, (uint8_t) (x >> 8));
write_reg(HX8347D_REG_ECL, (uint8_t) (x + cx -1));
write_reg(HX8347D_REG_ECH, (uint8_t) ((x + cx -1) >> 8));
write_reg(HX8347D_REG_SPL, (uint8_t) y);
write_reg(HX8347D_REG_SPH, (uint8_t) (y >> 8));
write_reg(HX8347D_REG_EPL, (uint8_t) (y + cy -1));
write_reg(HX8347D_REG_EPH, (uint8_t) ((y + cy -1) >> 8));
}
static inline void reset_viewport(void) {
set_viewport(0, 0, GDISP.Width, GDISP.Height);
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/**
* @brief Low level GDISP driver initialization.
*
* @notapi
*/
bool_t gdisp_lld_init(void) {
/* Initialise your display */
init_board();
// Hardware reset
setpin_reset(TRUE);
delayms(1);
setpin_reset(FALSE);
delayms(5);
// Get the bus for the following initialisation commands
acquire_bus();
/* Start Initial Sequence ----------------------------------------------------*/
write_reg(HX8347D_REG_STBAH, 0x00); /* Reset Power Control 1 */
write_reg(HX8347D_REG_STBAL, 0x20); /* Power Control 2 */
write_reg(HX8347D_REG_PTBAH, 0x0C); /* Power Control 1 */
write_reg(HX8347D_REG_PTBAL, 0xC4); /* Power Control 2 */
write_reg(HX8347D_REG_OPONN, 0x40); /* Source OPON_N */
write_reg(HX8347D_REG_OPONI, 0x38); /* Source OPON_I */
write_reg(HX8347D_REG_DC2, 0xA3); /* Display Control 2 */
/* Power On sequence ---------------------------------------------------------*/
write_reg(HX8347D_REG_PWC2, 0x1B); /* Power Control 2 */
write_reg(HX8347D_REG_PWC1, 0x01); /* Power Control 1 */
write_reg(HX8347D_REG_VMH, 0x2F); /* Vcom Control 2 */
write_reg(HX8347D_REG_VML, 0x57); /* Vcom Control 3 */
write_reg(HX8347D_REG_VMF, 0x8D); /* Vcom Control 1 */
/* Gamma settings -----------------------------------------------------------*/
write_reg(HX8347D_REG_VRP0,0x01); // default setup
write_reg(HX8347D_REG_VRP1,0x0e); //
write_reg(HX8347D_REG_VRP2,0x11); //
write_reg(HX8347D_REG_VRP3,0x1a); //
write_reg(HX8347D_REG_VRP4,0x18); //
write_reg(HX8347D_REG_VRP5,0x24); //
write_reg(HX8347D_REG_PRP0,0x15); //
write_reg(HX8347D_REG_PRP1,0x65); //
write_reg(HX8347D_REG_PKP0,0x0b); //
write_reg(HX8347D_REG_PKP1,0x18); //
write_reg(HX8347D_REG_PKP2,0x19); //
write_reg(HX8347D_REG_PKP3,0x1a); //
write_reg(HX8347D_REG_PKP4,0x18); //
write_reg(HX8347D_REG_VRN0,0x1b); //
write_reg(HX8347D_REG_VRN1,0x27); //
write_reg(HX8347D_REG_VRN2,0x25); //
write_reg(HX8347D_REG_VRN3,0x2e); //
write_reg(HX8347D_REG_VRN4,0x31); //
write_reg(HX8347D_REG_VRN5,0x3e); //
write_reg(HX8347D_REG_PRN0,0x1a); //
write_reg(HX8347D_REG_PRN1,0x6a); //
write_reg(HX8347D_REG_PKN0,0x07); //
write_reg(HX8347D_REG_PKN1,0x05); //
write_reg(HX8347D_REG_PKN2,0x06); //
write_reg(HX8347D_REG_PKN3,0x0b); //
write_reg(HX8347D_REG_PKN4,0x14); //
write_reg(HX8347D_REG_CGM,0xcc); //
/* Power + Osc ---------------------------------------------------------------*/
write_reg(HX8347D_REG_OSCCH, 0x36); /* OSC Control 1 */
write_reg(HX8347D_REG_OSCCL, 0x01); /* OSC Control 2 */
write_reg(HX8347D_REG_DMODE, 0x00); /* Display Mode Control */
write_reg(HX8347D_REG_PWC6, 0x88); /* Power Control 6 */
delayms(5); /* Delay 5 ms */
write_reg(HX8347D_REG_PWC6, 0x80); /* Power Control 6 */
delayms(5); /* Delay 5 ms */
write_reg(HX8347D_REG_PWC6, 0x90); /* Power Control 6 */
delayms(5); /* Delay 5 ms */
write_reg(HX8347D_REG_PWC6, 0xD0); /* Power Control 6 */
delayms(5); /* Delay 5 ms */
write_reg(HX8347D_REG_COLMOD, 0x05); /* Colmod 16Bit/Pixel */
write_reg(HX8347D_REG_PCH, 0x00); /* Panel Characteristic */
write_reg(HX8347D_REG_DC3, 0x38); /* Display Control 3 */
delayms(40);
write_reg(HX8347D_REG_DC3, 0x3C); /* Display Control 3 */
write_reg(HX8347D_REG_MAC, 0x08); /* Memory access control */
write_reg(HX8347D_REG_SCL, 0x00);
write_reg(HX8347D_REG_SCH, 0x00);
write_reg(HX8347D_REG_ECL, 0xef);
write_reg(HX8347D_REG_ECH, 0x00);
write_reg(HX8347D_REG_SPL, 0x00);
write_reg(HX8347D_REG_SPH, 0x00);
write_reg(HX8347D_REG_EPL, 0x3f);
write_reg(HX8347D_REG_EPH, 0x01);
// Release the bus
release_bus();
/* Turn on the backlight */
set_backlight(GDISP_INITIAL_BACKLIGHT);
/* Initialise the GDISP structure */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn;
GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
GDISP.Contrast = GDISP_INITIAL_CONTRAST;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
/**
* @brief Draws a pixel on the display.
*
* @param[in] x X location of the pixel
* @param[in] y Y location of the pixel
* @param[in] color The color of the pixel
*
* @notapi
*/
void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
#endif
acquire_bus();
set_cursor(x, y);
write_ram((color >> 8) & 0xFF, color & 0xFF);
release_bus();
}
/* ---- Optional Routines ---- */
/*
All the below routines are optional.
Defining them will increase speed but everything
will work if they are not defined.
If you are not using a routine - turn it off using
the appropriate GDISP_HARDWARE_XXXX macro.
Don't bother coding for obvious similar routines if
there is no performance penalty as the emulation software
makes a good job of using similar routines.
eg. If gfillarea() is defined there is little
point in defining clear() unless the
performance bonus is significant.
For good performance it is suggested to implement
fillarea() and blitarea().
*/
#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
/**
* @brief Clear the display.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] color The color of the pixel
*
* @notapi
*/
void gdisp_lld_clear(color_t color) {
unsigned i;
acquire_bus();
reset_viewport();
stream_start();
for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
write_ram16(color);
stream_stop();
release_bus();
}
#endif
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a color.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] color The color of the fill
*
* @notapi
*/
void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
unsigned i, area;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
area = cx*cy;
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
for(i = 0; i < area; i++)
write_ram16(color);
stream_stop();
release_bus();
}
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a bitmap.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @notapi
*/
void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
coord_t endx, endy;
unsigned lg;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
if (srcx+cx > srccx) cx = srccx - srcx;
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
endx = srcx + cx;
endy = y + cy;
lg = srccx - cx;
buffer += srcx + srcy * srccx;
for(; y < endy; y++, buffer += lg)
for(x=srcx; x < endx; x++)
write_data(*buffer++);
stream_stop();
release_bus();
}
#endif
#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
/**
* @brief Get the color of a particular pixel.
* @note Optional.
* @note If x,y is off the screen, the result is undefined.
*
* @param[in] x, y The pixel to be read
*
* @notapi
*/
color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
color_t color;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
#endif
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
/**
* @brief Scroll vertically a section of the screen.
* @note Optional.
* @note If x,y + cx,cy is off the screen, the result is undefined.
* @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
*
* @param[in] x, y The start of the area to be scrolled
* @param[in] cx, cy The size of the area to be scrolled
* @param[in] lines The number of lines to scroll (Can be positive or negative)
* @param[in] bgcolor The color to fill the newly exposed area.
*
* @notapi
*/
void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
coord_t row0, row1;
unsigned i, abslines, j;
static int gap;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
}
#endif
#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
/**
* @brief Driver Control
* @details Unsupported control codes are ignored.
* @note The value parameter should always be typecast to (void *).
* @note There are some predefined and some specific to the low level driver.
* @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
* GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
* GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
* that only supports off/on anything other
* than zero is on.
*
* @param[in] what What to do.
* @param[in] value The value to use (always cast to a void *).
*
* @notapi
*/
void gdisp_lld_control(unsigned what, void *value) {
switch(what) {
case GDISP_CONTROL_ORIENTATION:
if (GDISP.Orientation == (gdisp_orientation_t)value)
return;
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
acquire_bus();
write_reg(HX8347D_REG_MAC, 0x08); /* Memory access control */
write_reg(HX8347D_REG_ECL, 0xef);
write_reg(HX8347D_REG_ECH, 0x00);
write_reg(HX8347D_REG_EPL, 0x3f);
write_reg(HX8347D_REG_EPH, 0x01);
release_bus();
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
acquire_bus();
write_reg(HX8347D_REG_MAC, 0x68); /* Memory access control */
write_reg(HX8347D_REG_ECL, 0x3f);
write_reg(HX8347D_REG_ECH, 0x01);
write_reg(HX8347D_REG_EPL, 0xef);
write_reg(HX8347D_REG_EPH, 0x00);
release_bus();
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
acquire_bus();
write_reg(HX8347D_REG_MAC, 0xc8); /* Memory access control */
write_reg(HX8347D_REG_ECL, 0xef);
write_reg(HX8347D_REG_ECH, 0x00);
write_reg(HX8347D_REG_EPL, 0x3f);
write_reg(HX8347D_REG_EPH, 0x01);
release_bus();
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
acquire_bus();
write_reg(HX8347D_REG_MAC, 0xa8); /* Memory access control */
write_reg(HX8347D_REG_ECL, 0x3f);
write_reg(HX8347D_REG_ECH, 0x01);
write_reg(HX8347D_REG_EPL, 0xef);
write_reg(HX8347D_REG_EPH, 0x00);
release_bus();
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
GDISP.Orientation = (gdisp_orientation_t)value;
return;
case GDISP_CONTROL_BACKLIGHT:
if ((unsigned)value > 100)
value = (void *)100;
set_backlight((unsigned)value);
GDISP.Backlight = (unsigned)value;
return;
default:
return;
}
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/HX8347D/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/HX8347D

View File

@ -0,0 +1,202 @@
/*
* This file is subject to the terms of the GFX License, v1.0. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://chibios-gfx.com/license.html
*/
/**
* @file drivers/gdisp/HX8347D/gdisp_lld_board_embest_dmstf4bb.h
* @brief GDISP Graphic Driver subsystem board SPI interface for the HX8347D display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
#define SET_RST palSetPad(GPIOB, 8);
#define CLR_RST palClearPad(GPIOB, 8);
/* PWM configuration structure. We use timer 4 channel 2 (orange LED on board). */
static const PWMConfig pwmcfg = {
1000000, /* 1 MHz PWM clock frequency. */
100, /* PWM period is 100 cycles. */
NULL,
{
{PWM_OUTPUT_ACTIVE_HIGH, NULL},
{PWM_OUTPUT_ACTIVE_HIGH, NULL},
{PWM_OUTPUT_ACTIVE_HIGH, NULL},
{PWM_OUTPUT_ACTIVE_HIGH, NULL}
},
0
};
/*
* SPI1 configuration structure.
* Speed 42MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
* The slave select line is the pin 4 on the port GPIOA.
*/
static const SPIConfig spi1cfg1 = {
NULL,
/* HW dependent part.*/
GPIOA,
4,
0 //SPI_CR1_BR_0
};
/*
* SPI1 configuration structure.
* Speed 42MHz, CPHA=0, CPOL=0, 16bits frames, MSb transmitted first.
* The slave select line is the pin 4 on the port GPIOA.
*/
static const SPIConfig spi1cfg2 = {
NULL,
/* HW dependent part.*/
GPIOA,
4,
SPI_CR1_DFF //SPI_CR1_BR_0
};
/**
* @brief Initialise the board for the display.
* @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
*
* @notapi
*/
static inline void init_board(void) {
/* Display backlight control */
/* TIM4 is an alternate function 2 (AF2) */
pwmStart(&PWMD4, &pwmcfg);
palSetPadMode(GPIOD, 13, PAL_MODE_ALTERNATE(2));
pwmEnableChannel(&PWMD4, 1, 100);
palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST); /* RST */
palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST); /* RS */
/*
* Initializes the SPI driver 1. The SPI1 signals are routed as follow:
* PB12 - NSS.
* PB13 - SCK.
* PB14 - MISO.
* PB15 - MOSI.
*/
spiStart(&SPID1, &spi1cfg1);
palSetPad(GPIOA, 4);
palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL |
PAL_STM32_OSPEED_HIGHEST); /* NSS. */
palSetPadMode(GPIOA, 5, PAL_MODE_ALTERNATE(5) |
PAL_STM32_OSPEED_HIGHEST); /* SCK. */
palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(5)); /* MISO. */
palSetPadMode(GPIOA, 7, PAL_MODE_ALTERNATE(5) |
PAL_STM32_OSPEED_HIGHEST); /* MOSI. */
}
/**
* @brief Set or clear the lcd reset pin.
*
* @param[in] state TRUE = lcd in reset, FALSE = normal operation
*
* @notapi
*/
static inline void setpin_reset(bool_t state) {
if (state) {
CLR_RST;
} else {
SET_RST;
}
}
/**
* @brief Set the lcd back-light level.
*
* @param[in] percent 0 to 100%
*
* @notapi
*/
static inline void set_backlight(uint8_t percent) {
pwmEnableChannel(&PWMD4, 1, percent);
}
/**
* @brief Take exclusive control of the bus
* @note Not needed, not implemented
*
* @notapi
*/
static inline void acquire_bus(void) {
spiAcquireBus(&SPID1);
}
/**
* @brief Release exclusive control of the bus
* @note Not needed, not implemented
*
* @notapi
*/
static inline void release_bus(void) {
spiReleaseBus(&SPID1);
}
/**
* @brief Send data to the index register.
*
* @param[in] index The index register to set
*
* @notapi
*/
static inline void write_index(uint8_t cmd) {
palClearPad(GPIOB, 9);
palClearPad(GPIOA, 4);
while((SPI1->SR & SPI_SR_TXE) == 0);
SPI1->DR = cmd;
while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
palSetPad(GPIOB, 9);
}
/**
* @brief Send data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static inline void write_data(uint8_t data) {
SPI1->DR = data;
while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
palSetPad(GPIOA, 4);
}
static inline void write_ram8(uint8_t data1, uint8_t data2) {
SPI1->DR = data1;
while((SPI1->SR & SPI_SR_TXE) == 0);
SPI1->DR = data2;
while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
palSetPad(GPIOA, 4);
}
static inline void write_ram16(uint16_t data) {
while((SPI1->SR & SPI_SR_TXE) == 0);
SPI1->DR = data;
}
#if GDISP_HARDWARE_READPIXEL || defined(__DOXYGEN__)
/**
* @brief Read data from the lcd.
*
* @return The data from the lcd
* @note The chip select may need to be asserted/de-asserted
* around the actual spi read
*
* @notapi
*/
static inline uint16_t read_data(void) {
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,39 @@
/*
* This file is subject to the terms of the GFX License, v1.0. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://chibios-gfx.com/license.html
*/
/**
* @file drivers/gdisp/HX8347D/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header for the HX8347D display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "HX8347D"
#define GDISP_HARDWARE_CLEARS TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_SCROLL FALSE
#define GDISP_HARDWARE_PIXELREAD FALSE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,24 @@
Description:
Driver for LCD with 4-wire serial interface (65k colors).
To use this driver:
1. Add in your halconf.h:
a) #define GFX_USE_GDISP TRUE
b) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD
c) If you are not using a known board then create a gdisp_lld_board.h file
and ensure it is on your include path.
Use the gdisp_lld_board_st_stm32f4_discovery.h file as a basis.
Currently known boards are:
BOARD_ST_STM32F4_DISCOVERY
Board configuration assume that you have STM32_PWM_USE_TIM4 set to TRUE in your mcuconf.h.
d) The following are optional - define them if you are not using the defaults below:
#define GDISP_SCREEN_WIDTH 240
#define GDISP_SCREEN_HEIGHT 320
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/HX8347D/gdisp_lld.mk

View File

@ -31,6 +31,7 @@ FEATURE: Simplified assigning inputs to buttons and sliders
FIX: Some fixes for the HD44780 TDISP driver by the user 'Frysk'
FEATURE: Added ILI9481 by user 'Abhishek'
FEATURE: Added enable/disable functions for widgets (Buttons)
FEATURE: Added HX8347D driver by user 'Eddie'
*** changes after 1.4 ***