SSD2119: first working version of driver

It is a mix of barely changed few drivers already present in ChibiOS/GFX
project. No other routines than initialization ones were changed.
Properly displays "basics" demo.

Main features and changes:
- Based on SSD1289 and SSD1121 in FSMC mode.
- Uses FSMC module. Maybe oneday I will make GPIO version.
- LCD backlight PWM input is tied high (no timer yet).
- Added ssd2119.h with SSD2119 registers' addresses.
- Updated set_cursor and set_viewport functions. Not thoroughly tested,
  however.
- Rewritten GDISP_LLD(init)(void) function.
This commit is contained in:
resset 2013-02-05 23:39:48 +01:00
parent cb81a0f3fc
commit e097426338
3 changed files with 213 additions and 115 deletions

View File

@ -30,6 +30,8 @@
#include "hal.h"
#include "gfx.h"
#include "ssd2119.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
@ -40,10 +42,10 @@
/*===========================================================================*/
#ifndef GDISP_SCREEN_HEIGHT
#define GDISP_SCREEN_HEIGHT 320
#define GDISP_SCREEN_HEIGHT 240
#endif
#ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 240
#define GDISP_SCREEN_WIDTH 320
#endif
#define GDISP_INITIAL_CONTRAST 50
@ -56,8 +58,6 @@
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif defined(BOARD_FIREBULL_STM32_F103)
#include "gdisp_lld_board_firebullstm32f103.h"
#elif defined(BOARD_EMBEST_DMSTF4BB)
#include "gdisp_lld_board_embest_dmstf4bb.h"
#else
@ -73,26 +73,26 @@
#define delayms(ms) chThdSleepMilliseconds(ms)
static __inline void set_cursor(coord_t x, coord_t y) {
/* Reg 0x004E is an 8 bit value
* Reg 0x004F is 9 bit
/* Reg SSD2119_REG_X_RAM_ADDR is 9 bit value
* Reg SSD2119_REG_Y_RAM_ADDR is an 8 bit
* Use a bit mask to make sure they are not set too high
*/
switch(GDISP.Orientation) {
case GDISP_ROTATE_180:
write_reg(0x004e, (GDISP_SCREEN_WIDTH-1-x) & 0x00FF);
write_reg(0x004f, (GDISP_SCREEN_HEIGHT-1-y) & 0x01FF);
write_reg(SSD2119_REG_X_RAM_ADDR, (GDISP_SCREEN_WIDTH - 1 - x) & 0x01FF);
write_reg(SSD2119_REG_Y_RAM_ADDR, (GDISP_SCREEN_HEIGHT - 1 - y) & 0x00FF);
break;
case GDISP_ROTATE_0:
write_reg(0x004e, x & 0x00FF);
write_reg(0x004f, y & 0x01FF);
write_reg(SSD2119_REG_X_RAM_ADDR, x & 0x01FF);
write_reg(SSD2119_REG_Y_RAM_ADDR, y & 0x00FF);
break;
case GDISP_ROTATE_270:
write_reg(0x004e, y & 0x00FF);
write_reg(0x004f, x & 0x01FF);
write_reg(SSD2119_REG_X_RAM_ADDR, y & 0x01FF);
write_reg(SSD2119_REG_Y_RAM_ADDR, x & 0x00FF);
break;
case GDISP_ROTATE_90:
write_reg(0x004e, (GDISP_SCREEN_WIDTH - y - 1) & 0x00FF);
write_reg(0x004f, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF);
write_reg(SSD2119_REG_X_RAM_ADDR, (GDISP_SCREEN_WIDTH - y - 1) & 0x01FF);
write_reg(SSD2119_REG_Y_RAM_ADDR, (GDISP_SCREEN_HEIGHT - x - 1) & 0x00FF);
break;
}
}
@ -101,35 +101,35 @@ static void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
set_cursor(x, y);
/* Reg 0x44 - Horizontal RAM address position
* Upper Byte - HEA
* Lower Byte - HSA
* 0 <= HSA <= HEA <= 0xEF
* Reg 0x45,0x46 - Vertical RAM address position
* Lower 9 bits gives 0-511 range in each value
* 0 <= Reg(0x45) <= Reg(0x46) <= 0x13F
/* Reg 0x44 - Vertical RAM address position
* Upper Byte - VEA
* Lower Byte - VSA
* 0 <= VSA <= VEA <= 0xEF
* Reg 0x45,0x46 - Horizontal RAM address position
* Lower 9 bits gives 0-511 range in each value, HSA and HEA respectively
* 0 <= HSA <= HEA <= 0x13F
*/
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
write_reg(0x44, (((x+cx-1) << 8) & 0xFF00 ) | (x & 0x00FF));
write_reg(0x45, y & 0x01FF);
write_reg(0x46, (y+cy-1) & 0x01FF);
write_reg(SSD2119_REG_V_RAM_POS, (((y + cy - 1) << 8) & 0xFF00 ) | (y & 0x00FF));
write_reg(SSD2119_REG_H_RAM_START, (x & 0x01FF));
write_reg(SSD2119_REG_H_RAM_END, (x + cx - 1) & 0x01FF);
break;
case GDISP_ROTATE_270:
write_reg(0x44, (((x+cx-1) << 8) & 0xFF00 ) | (y & 0x00FF));
write_reg(0x45, x & 0x01FF);
write_reg(0x46, (x+cx-1) & 0x01FF);
write_reg(SSD2119_REG_V_RAM_POS, (((y + cy - 1) << 8) & 0xFF00 ) | (x & 0x00FF));
write_reg(SSD2119_REG_H_RAM_START, (y & 0x01FF));
write_reg(SSD2119_REG_H_RAM_END, (y + cy - 1) & 0x01FF);
break;
case GDISP_ROTATE_180:
write_reg(0x44, (((GDISP_SCREEN_WIDTH-x-1) & 0x00FF) << 8) | ((GDISP_SCREEN_WIDTH - (x+cx)) & 0x00FF));
write_reg(0x45, (GDISP_SCREEN_HEIGHT-(y+cy)) & 0x01FF);
write_reg(0x46, (GDISP_SCREEN_HEIGHT-y-1) & 0x01FF);
write_reg(SSD2119_REG_V_RAM_POS, (((GDISP_SCREEN_HEIGHT - y - 1) & 0x00FF) << 8) | ((GDISP_SCREEN_HEIGHT - (y + cy)) & 0x00FF));
write_reg(SSD2119_REG_H_RAM_START, (GDISP_SCREEN_WIDTH - (x + cx)) & 0x01FF);
write_reg(SSD2119_REG_H_RAM_END, (GDISP_SCREEN_WIDTH - x - 1) & 0x01FF);
break;
case GDISP_ROTATE_90:
write_reg(0x44, (((GDISP_SCREEN_WIDTH - y - 1) & 0x00FF) << 8) | ((GDISP_SCREEN_WIDTH - (y+cy)) & 0x00FF));
write_reg(0x45, (GDISP_SCREEN_HEIGHT - (x+cx)) & 0x01FF);
write_reg(0x46, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF);
write_reg(SSD2119_REG_V_RAM_POS, (((GDISP_SCREEN_HEIGHT - x - 1) & 0x00FF) << 8) | ((GDISP_SCREEN_HEIGHT - (x + cx)) & 0x00FF));
write_reg(SSD2119_REG_H_RAM_START, (GDISP_SCREEN_WIDTH - (y + cy)) & 0x01FF);
write_reg(SSD2119_REG_H_RAM_END, (GDISP_SCREEN_WIDTH - y - 1) & 0x01FF);
break;
}
@ -171,52 +171,70 @@ bool_t GDISP_LLD(init)(void) {
// Get the bus for the following initialisation commands
acquire_bus();
write_reg(0x0000,0x0001); delay(5);
write_reg(0x0003,0xA8A4); delay(5);
write_reg(0x000C,0x0000); delay(5);
write_reg(0x000D,0x080C); delay(5);
write_reg(0x000E,0x2B00); delay(5);
write_reg(0x001E,0x00B0); delay(5);
write_reg(0x0001,0x2B3F); delay(5);
write_reg(0x0002,0x0600); delay(5);
write_reg(0x0010,0x0000); delay(5);
write_reg(0x0011,0x6070); delay(5);
write_reg(0x0005,0x0000); delay(5);
write_reg(0x0006,0x0000); delay(5);
write_reg(0x0016,0xEF1C); delay(5);
write_reg(0x0017,0x0003); delay(5);
write_reg(0x0007,0x0133); delay(5);
write_reg(0x000B,0x0000); delay(5);
write_reg(0x000F,0x0000); delay(5);
write_reg(0x0041,0x0000); delay(5);
write_reg(0x0042,0x0000); delay(5);
write_reg(0x0048,0x0000); delay(5);
write_reg(0x0049,0x013F); delay(5);
write_reg(0x004A,0x0000); delay(5);
write_reg(0x004B,0x0000); delay(5);
write_reg(0x0044,0xEF00); delay(5);
write_reg(0x0045,0x0000); delay(5);
write_reg(0x0046,0x013F); delay(5);
write_reg(0x0030,0x0707); delay(5);
write_reg(0x0031,0x0204); delay(5);
write_reg(0x0032,0x0204); delay(5);
write_reg(0x0033,0x0502); delay(5);
write_reg(0x0034,0x0507); delay(5);
write_reg(0x0035,0x0204); delay(5);
write_reg(0x0036,0x0204); delay(5);
write_reg(0x0037,0x0502); delay(5);
write_reg(0x003A,0x0302); delay(5);
write_reg(0x003B,0x0302); delay(5);
write_reg(0x0023,0x0000); delay(5);
write_reg(0x0024,0x0000); delay(5);
write_reg(0x0025,0x8000); delay(5);
write_reg(0x004f,0x0000); delay(5);
write_reg(0x004e,0x0000); delay(5);
write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0001);
delay(5);
write_reg(SSD2119_REG_PWR_CTRL_5, 0x00B2);
delay(5);
write_reg(SSD2119_REG_VCOM_OTP_1, 0x0006);
delay(5);
write_reg(SSD2119_REG_OSC_START, 0x0001);
delay(5);
write_reg(SSD2119_REG_OUTPUT_CTRL, 0x30EF);
delay(5);
write_reg(SSD2119_REG_LCD_DRIVE_AC_CTRL, 0x0600);
delay(5);
write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0000);
delay(5);
write_reg(SSD2119_REG_ENTRY_MODE, 0x6830); // ENTRY_MODE_DEFAULT
delay(5);
write_reg(SSD2119_REG_SLEEP_MODE_2, 0x0999);
delay(5);
write_reg(SSD2119_REG_ANALOG_SET, 0x3800);
delay(5);
write_reg(SSD2119_REG_DISPLAY_CTRL, 0x0033);
delay(5);
write_reg(SSD2119_REG_PWR_CTRL_2, 0x0005);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_1, 0x0000);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_2, 0x0303);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_3, 0x0407);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_4, 0x0301);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_5, 0x0301);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_6, 0x0403);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_7, 0x0707);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_8, 0x0400);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_9, 0x0a00);
delay(5);
write_reg(SSD2119_REG_GAMMA_CTRL_10, 0x1000);
delay(5);
write_reg(SSD2119_REG_PWR_CTRL_3, 0x000A);
delay(5);
write_reg(SSD2119_REG_PWR_CTRL_4, 0x2E00);
delay(5);
write_reg(SSD2119_REG_V_RAM_POS, (GDISP_SCREEN_HEIGHT - 1) << 8);
delay(5);
write_reg(SSD2119_REG_H_RAM_START, 0x0000);
delay(5);
write_reg(SSD2119_REG_H_RAM_END, GDISP_SCREEN_WIDTH - 1);
delay(5);
write_reg(SSD2119_REG_X_RAM_ADDR, 0x00);
delay(5);
write_reg(SSD2119_REG_Y_RAM_ADDR, 0x00);
delay(5);
// Release the bus
release_bus();
/* Turn on the back-light */
set_backlight(GDISP_INITIAL_BACKLIGHT);

View File

@ -29,14 +29,12 @@
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
#define SET_CS palSetPad(GPIOD, 12);
#define CLR_CS palClearPad(GPIOD, 12);
#define SET_RS palSetPad(GPIOD, 13);
#define CLR_RS palClearPad(GPIOD, 13);
#define SET_WR palSetPad(GPIOD, 14);
#define CLR_WR palClearPad(GPIOD, 14);
#define SET_RD palSetPad(GPIOD, 15);
#define CLR_RD palClearPad(GPIOD, 15);
/* Using FSMC A19 (PE3) as DC */
#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* DC = 0 */
#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* DC = 1 */
#define SET_RST palSetPad(GPIOD, 3);
#define CLR_RST palClearPad(GPIOD, 3);
/**
* @brief Initialise the board for the display.
@ -45,20 +43,38 @@
* @notapi
*/
static __inline void init_board(void) {
palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, 12, PAL_MODE_OUTPUT_PUSHPULL);
unsigned char FSMC_Bank;
/* STM32F2-F4 FSMC init */
rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
/* set pins to FSMC mode */
IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
(1 << 9) | (1 << 10) | (1 << 14) | (1 << 15), 0};
IOBus busE = {GPIOE, (1 << 3) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
(1 << 13) | (1 << 14) | (1 << 15), 0};
/* FSMC is an alternate function 12 (AF12). */
palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
FSMC_Bank = 0;
/* FSMC timing */
FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
| (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
| (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
/* Bank1 NOR/SRAM control register configuration
* This is actually not needed as already set by default after reset */
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
/* Display backlight always on. */
palSetPadMode(GPIOD, 13, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, 14, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL);
// Configure the pins to a well know state
SET_RS;
SET_RD;
SET_WR;
CLR_CS;
palSetPad(GPIOD, 13);
}
/**
* @brief Set or clear the lcd reset pin.
*
@ -67,8 +83,11 @@ static __inline void init_board(void) {
* @notapi
*/
static __inline void setpin_reset(bool_t state) {
(void) state;
/* Nothing to do here - reset pin tied to Vcc */
if (state) {
CLR_RST;
} else {
SET_RST;
}
}
/**
@ -85,6 +104,7 @@ static __inline void set_backlight(uint8_t percent) {
/**
* @brief Take exclusive control of the bus
* @note Not needed, not implemented
*
* @notapi
*/
@ -94,6 +114,7 @@ static __inline void acquire_bus(void) {
/**
* @brief Release exclusive control of the bus
* @note Not needed, not implemented
*
* @notapi
*/
@ -109,8 +130,7 @@ static __inline void release_bus(void) {
* @notapi
*/
static __inline void write_index(uint16_t index) {
palWritePort(GPIOE, index);
CLR_RS; CLR_WR; SET_WR; SET_RS;
GDISP_REG = index;
}
/**
@ -121,8 +141,7 @@ static __inline void write_index(uint16_t index) {
* @notapi
*/
static __inline void write_data(uint16_t data) {
palWritePort(GPIOE, data);
CLR_WR; SET_WR;
GDISP_RAM = data;
}
#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
@ -136,20 +155,7 @@ static __inline void write_data(uint16_t data) {
* @notapi
*/
static __inline uint16_t read_data(void) {
uint16_t value;
// change pin mode to digital input
palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
CLR_RD;
value = palReadPort(GPIOE);
value = palReadPort(GPIOE);
SET_RD;
// change pin mode back to digital output
palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
return value;
return GDISP_RAM;
}
#endif

View File

@ -0,0 +1,74 @@
/*
ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SSD2119_H
#define _SSD2119_H
/* SSD2119 registers */
#define SSD2119_REG_DEVICE_CODE_READ 0x00
#define SSD2119_REG_OSC_START 0x00
#define SSD2119_REG_OUTPUT_CTRL 0x01
#define SSD2119_REG_LCD_DRIVE_AC_CTRL 0x02
#define SSD2119_REG_PWR_CTRL_1 0x03
#define SSD2119_REG_DISPLAY_CTRL 0x07
#define SSD2119_REG_FRAME_CYCLE_CTRL 0x0B
#define SSD2119_REG_PWR_CTRL_2 0x0C
#define SSD2119_REG_PWR_CTRL_3 0x0D
#define SSD2119_REG_PWR_CTRL_4 0x0E
#define SSD2119_REG_GATE_SCAN_START 0x0F
#define SSD2119_REG_SLEEP_MODE_1 0x10
#define SSD2119_REG_ENTRY_MODE 0x11
#define SSD2119_REG_SLEEP_MODE_2 0x12
#define SSD2119_REG_GEN_IF_CTRL 0x15
#define SSD2119_REG_H_PORCH 0x16
#define SSD2119_REG_V_PORCH 0x17
#define SSD2119_REG_PWR_CTRL_5 0x1E
#define SSD2119_REG_UNIFORMITY 0x20
#define SSD2119_REG_RAM_DATA 0x22
#define SSD2119_REG_FRAME_FREQ 0x25
#define SSD2119_REG_ANALOG_SET 0x26
#define SSD2119_REG_VCOM_OTP_1 0x28
#define SSD2119_REG_VCOM_OTP_2 0x29
#define SSD2119_REG_GAMMA_CTRL_1 0x30
#define SSD2119_REG_GAMMA_CTRL_2 0x31
#define SSD2119_REG_GAMMA_CTRL_3 0x32
#define SSD2119_REG_GAMMA_CTRL_4 0x33
#define SSD2119_REG_GAMMA_CTRL_5 0x34
#define SSD2119_REG_GAMMA_CTRL_6 0x35
#define SSD2119_REG_GAMMA_CTRL_7 0x36
#define SSD2119_REG_GAMMA_CTRL_8 0x37
#define SSD2119_REG_GAMMA_CTRL_9 0x3A
#define SSD2119_REG_GAMMA_CTRL_10 0x3B
#define SSD2119_REG_V_SCROLL_1 0x41
#define SSD2119_REG_V_SCROLL_2 0x42
#define SSD2119_REG_V_RAM_POS 0x44
#define SSD2119_REG_H_RAM_START 0x45
#define SSD2119_REG_H_RAM_END 0x46
#define SSD2119_REG_1_DRV_POS_1 0x48
#define SSD2119_REG_1_DRV_POS_2 0x49
#define SSD2119_REG_2_DRV_POS_1 0x4A
#define SSD2119_REG_2_DRV_POS_2 0x4B
#define SSD2119_REG_X_RAM_ADDR 0x4E
#define SSD2119_REG_Y_RAM_ADDR 0x4F
/* SSD2119 commands */
#endif // _SSD2119_H