From 0ef5bf9dfca957c1a0c5ae55e62ab9a7ffe7671b Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Thu, 22 Nov 2012 21:21:34 +0100 Subject: ported S6D1121 driver --- drivers/gdisp/S6D1121/gdisp_lld.c | 375 ++++++++++++--------- drivers/gdisp/S6D1121/gdisp_lld_board_example.h | 125 +++++++ .../gdisp/S6D1121/gdisp_lld_board_olimex_e407.h | 94 ++++++ drivers/gdisp/S6D1121/gdisp_lld_config.h | 2 +- drivers/gdisp/S6D1121/readme.txt | 8 +- drivers/gdisp/S6D1121/s6d1121_lld.c.h | 254 -------------- 6 files changed, 438 insertions(+), 420 deletions(-) create mode 100644 drivers/gdisp/S6D1121/gdisp_lld_board_example.h create mode 100644 drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h delete mode 100644 drivers/gdisp/S6D1121/s6d1121_lld.c.h (limited to 'drivers/gdisp') diff --git a/drivers/gdisp/S6D1121/gdisp_lld.c b/drivers/gdisp/S6D1121/gdisp_lld.c index 5eaa8e73..5f5d385a 100644 --- a/drivers/gdisp/S6D1121/gdisp_lld.c +++ b/drivers/gdisp/S6D1121/gdisp_lld.c @@ -35,147 +35,192 @@ /* Include the emulation code for things we don't support */ #include "gdisp_emulation.c" -#include "s6d1121_lld.c.h" - /*===========================================================================*/ -/* Driver interrupt handlers. */ +/* 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 100 + /*===========================================================================*/ -/* Driver exported functions. */ +/* Driver local definitions. */ /*===========================================================================*/ -/* ---- Required Routines ---- */ -/* - The following 2 routines are required. - All other routines are optional. -*/ +#if defined(BOARD_OLIMEX_STM32_E407) + #include "gdisp_lld_board_olimex_e407.h" +#else + #include "gdisp_lld_board.h" +#endif + +/* Some common routines and macros */ +#define write_reg(reg, data) { write_index(reg); write_data(data); } +#define stream_start() write_index(0x0022); +#define stream_stop() +#define delay(us) chThdSleepMicroseconds(us) +#define delayms(ms) chThdSleepMilliseconds(ms) + +static __inline void set_cursor(coord_t x, coord_t y) { + /* R20h - 8 bit + * R21h - 9 bit + */ + switch(GDISP.Orientation) { + case GDISP_ROTATE_0: + write_reg(0x0020, x & 0x00FF); + write_reg(0x0021, y & 0x01FF); + break; + case GDISP_ROTATE_90: + /* Note X has already been mirrored, so we do it directly */ + write_reg(0x0020, y & 0x00FF); + write_reg(0x0021, x & 0x01FF); + break; + case GDISP_ROTATE_180: + write_reg(0x0020, (GDISP_SCREEN_WIDTH - 1 - x) & 0x00FF); + write_reg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - y) & 0x01FF); + break; + case GDISP_ROTATE_270: + write_reg(0x0020, (GDISP_SCREEN_WIDTH - 1 - y) & 0x00FF); + write_reg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - x) & 0x01FF); + break; + } +} + +static __inline void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) { + /* HSA / HEA are 8 bit + * VSA / VEA are 9 bit + * use masks 0x00FF and 0x01FF to enforce this + */ + + switch(GDISP.Orientation) { + case GDISP_ROTATE_0: + write_reg(0x46, (((x + cx - 1) << 8) & 0xFF00 ) | + (x & 0x00FF)); + + write_reg(0x48, y & 0x01FF); + write_reg(0x47, (y + cy - 1) & 0x01FF); + break; + case GDISP_ROTATE_90: + write_reg(0x46, (((y + cy - 1) << 8) & 0xFF00) | + (y & 0x00FF)); + + write_reg(0x48, x & 0x01FF); + write_reg(0x47, (x + cx - 1) & 0x01FF); + break; + case GDISP_ROTATE_180: + write_reg(0x46, (((GDISP_SCREEN_WIDTH - x - 1) & 0x00FF) << 8) | + ((GDISP_SCREEN_WIDTH - (x + cx)) & 0x00FF)); + write_reg(0x48, (GDISP_SCREEN_HEIGHT - (y + cy)) & 0x01FF); + write_reg(0x47, (GDISP_SCREEN_HEIGHT- y - 1) & 0x01FF); + break; + case GDISP_ROTATE_270: + write_reg(0x46, (((GDISP_SCREEN_WIDTH - y - 1) & 0x00FF) << 8) | + ((GDISP_SCREEN_WIDTH - (y + cy)) & 0x00FF)); + write_reg(0x48, (GDISP_SCREEN_HEIGHT - (x + cx)) & 0x01FF); + write_reg(0x47, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF); + break; + } + + set_cursor(x, y); +} + +static __inline void reset_viewport(void) { + switch(GDISP.Orientation) { + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + set_viewport(0, 0, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT); + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + set_viewport(0, 0, GDISP_SCREEN_HEIGHT, GDISP_SCREEN_WIDTH); + break; + } +} -/** - * @brief Low level GDISP driver initialization. - * - * @notapi - */ bool_t GDISP_LLD(init)(void) { - palSetPadMode(GDISP_RST_GPIO, GDISP_RST_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); - // A Good idea to reset the module before using - GDISP_RST_LOW; - s6d1121_delay(2); - GDISP_RST_HIGH; // Hardware Reset - s6d1121_delay(2); - - #ifdef GDISP_USE_GPIO - // IO Default Configurations - palSetPadMode(GDISP_CS_GPIO, GDISP_CS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); - palSetPadMode(GDISP_WR_GPIO, GDISP_WR_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); - palSetPadMode(GDISP_RD_GPIO, GDISP_RD_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); - palSetPadMode(GDISP_RS_GPIO, GDISP_RS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); - palSetPadMode(GDISP_BL_GPIO, GDISP_BL_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); - - palSetGroupMode(GDISP_D0_GPIO, 0x0000000F, 0, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); - palSetGroupMode(GDISP_D4_GPIO, 0x0000FFF0, 0, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); - - GDISP_CS_HIGH; - GDISP_RD_HIGH; - GDISP_WR_HIGH; - GDISP_BL_LOW; - - #elif defined(GDISP_USE_FSMC) - #if defined(STM32F1XX) - /* FSMC setup. TODO: this only works for STM32F1 */ - rccEnableAHB(RCC_AHBENR_FSMCEN, 0); - - /* TODO: pin setup */ - #elif defined(STM32F4XX) - /* STM32F4 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 << 11) | (1 << 14) | (1 << 15), 0}; - - IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | - (1 << 13) | (1 << 14) | (1 << 15), 0}; - - palSetBusMode(&busD, PAL_MODE_ALTERNATE(12)); - palSetBusMode(&busE, PAL_MODE_ALTERNATE(12)); - #else - #error "FSMC not implemented for this device" - #endif + /* initialize the hardware */ + init_board(); - int FSMC_Bank = 0; - /* FSMC timing */ - FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16); + /* Hardware reset */ + setpin_reset(TRUE); + delayms(20); + setpin_reset(TRUE); + delayms(20); - /* Bank1 NOR/SRAM control register configuration */ - FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; - #endif + /* Get the bus for the following initialisation commands */ + acquire_bus(); - lld_lcdWriteReg(0x11,0x2004); - lld_lcdWriteReg(0x13,0xCC00); - lld_lcdWriteReg(0x15,0x2600); - lld_lcdWriteReg(0x14,0x252A); - lld_lcdWriteReg(0x12,0x0033); - lld_lcdWriteReg(0x13,0xCC04); + write_reg(0x11,0x2004); + write_reg(0x13,0xCC00); + write_reg(0x15,0x2600); + write_reg(0x14,0x252A); + write_reg(0x12,0x0033); + write_reg(0x13,0xCC04); - s6d1121_delay(1); + delayms(1); - lld_lcdWriteReg(0x13,0xCC06); + write_reg(0x13,0xCC06); - s6d1121_delay(1); + delayms(1); - lld_lcdWriteReg(0x13,0xCC4F); + write_reg(0x13,0xCC4F); - s6d1121_delay(1); + delayms(1); - lld_lcdWriteReg(0x13,0x674F); - lld_lcdWriteReg(0x11,0x2003); + write_reg(0x13,0x674F); + write_reg(0x11,0x2003); - s6d1121_delay(1); + delayms(1); // Gamma Setting - lld_lcdWriteReg(0x30,0x2609); - lld_lcdWriteReg(0x31,0x242C); - lld_lcdWriteReg(0x32,0x1F23); - lld_lcdWriteReg(0x33,0x2425); - lld_lcdWriteReg(0x34,0x2226); - lld_lcdWriteReg(0x35,0x2523); - lld_lcdWriteReg(0x36,0x1C1A); - lld_lcdWriteReg(0x37,0x131D); - lld_lcdWriteReg(0x38,0x0B11); - lld_lcdWriteReg(0x39,0x1210); - lld_lcdWriteReg(0x3A,0x1315); - lld_lcdWriteReg(0x3B,0x3619); - lld_lcdWriteReg(0x3C,0x0D00); - lld_lcdWriteReg(0x3D,0x000D); - - lld_lcdWriteReg(0x16,0x0007); - lld_lcdWriteReg(0x02,0x0013); - lld_lcdWriteReg(0x03,0x0003); - lld_lcdWriteReg(0x01,0x0127); - - s6d1121_delay(1); - - lld_lcdWriteReg(0x08,0x0303); - lld_lcdWriteReg(0x0A,0x000B); - lld_lcdWriteReg(0x0B,0x0003); - lld_lcdWriteReg(0x0C,0x0000); - lld_lcdWriteReg(0x41,0x0000); - lld_lcdWriteReg(0x50,0x0000); - lld_lcdWriteReg(0x60,0x0005); - lld_lcdWriteReg(0x70,0x000B); - lld_lcdWriteReg(0x71,0x0000); - lld_lcdWriteReg(0x78,0x0000); - lld_lcdWriteReg(0x7A,0x0000); - lld_lcdWriteReg(0x79,0x0007); - lld_lcdWriteReg(0x07,0x0051); - - s6d1121_delay(1); - - lld_lcdWriteReg(0x07,0x0053); - lld_lcdWriteReg(0x79,0x0000); - - lld_lcdResetViewPort(); + write_reg(0x30,0x2609); + write_reg(0x31,0x242C); + write_reg(0x32,0x1F23); + write_reg(0x33,0x2425); + write_reg(0x34,0x2226); + write_reg(0x35,0x2523); + write_reg(0x36,0x1C1A); + write_reg(0x37,0x131D); + write_reg(0x38,0x0B11); + write_reg(0x39,0x1210); + write_reg(0x3A,0x1315); + write_reg(0x3B,0x3619); + write_reg(0x3C,0x0D00); + write_reg(0x3D,0x000D); + + write_reg(0x16,0x0007); + write_reg(0x02,0x0013); + write_reg(0x03,0x0003); + write_reg(0x01,0x0127); + + delayms(1); + + write_reg(0x08,0x0303); + write_reg(0x0A,0x000B); + write_reg(0x0B,0x0003); + write_reg(0x0C,0x0000); + write_reg(0x41,0x0000); + write_reg(0x50,0x0000); + write_reg(0x60,0x0005); + write_reg(0x70,0x000B); + write_reg(0x71,0x0000); + write_reg(0x78,0x0000); + write_reg(0x7A,0x0000); + write_reg(0x79,0x0007); + write_reg(0x07,0x0051); + + delayms(1); + + write_reg(0x07,0x0053); + write_reg(0x79,0x0000); + + reset_viewport(); + set_backlight(GDISP_INITIAL_BACKLIGHT); /* Now initialise the GDISP structure */ GDISP.Width = GDISP_SCREEN_WIDTH; @@ -206,8 +251,11 @@ void GDISP_LLD(drawpixel)(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 - lld_lcdSetCursor(x, y); - lld_lcdWriteReg(0x0022, color); + + acquire_bus(); + set_cursor(x, y); + write_reg(0x0022, color); + release_bus(); } /* ---- Optional Routines ---- */ @@ -224,13 +272,15 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { void GDISP_LLD(clear)(color_t color) { unsigned i; - lld_lcdSetCursor(0, 0); - lld_lcdWriteStreamStart(); + acquire_bus(); + set_cursor(0, 0); + stream_start(); for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++) - lld_lcdWriteData(color); + write_data(color); - lld_lcdWriteStreamStop(); + stream_stop(); + release_bus(); } #endif @@ -257,12 +307,14 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { #endif area = cx*cy; - lld_lcdSetViewPort(x, y, cx, cy); - lld_lcdWriteStreamStart(); + acquire_bus(); + set_viewport(x, y, cx, cy); + stream_start(); for(i = 0; i < area; i++) - lld_lcdWriteData(color); - lld_lcdWriteStreamStop(); - lld_lcdResetViewPort(); + write_data(color); + stream_stop(); + reset_viewport(); + release_bus(); } #endif @@ -292,8 +344,9 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif - lld_lcdSetViewPort(x, y, cx, cy); - lld_lcdWriteStreamStart(); + acquire_bus(); + set_viewport(x, y, cx, cy); + stream_start(); endx = srcx + cx; endy = y + cy; @@ -301,9 +354,10 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { buffer += srcx + srcy * srccx; for(; y < endy; y++, buffer += lg) for(x=srcx; x < endx; x++) - lld_lcdWriteData(*buffer++); - lld_lcdWriteStreamStop(); - lld_lcdResetViewPort(); + write_data(*buffer++); + stream_stop(); + reset_viewport(); + release_bus(); } #endif @@ -328,13 +382,15 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0; #endif - lld_lcdSetCursor(x, y); - lld_lcdWriteStreamStart(); + aquire_bus(); + set_cursor(x, y); + stream_start(); color = lld_lcdReadData(); color = lld_lcdReadData(); - lld_lcdWriteStreamStop(); + stream_stop(); + release_bus(); return color; } @@ -371,6 +427,8 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { #endif abslines = lines < 0 ? -lines : lines; + + acquire_bus(); if (abslines >= cy) { abslines = cy; gap = 0; @@ -386,25 +444,26 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { } /* read row0 into the buffer and then write at row1*/ - lld_lcdSetViewPort(x, row0, cx, 1); + set_viewport(x, row0, cx, 1); lld_lcdReadStreamStart(); lld_lcdReadStream(buf, cx); lld_lcdReadStreamStop(); - lld_lcdSetViewPort(x, row1, cx, 1); - lld_lcdWriteStreamStart(); - lld_lcdWriteStream(buf, cx); - lld_lcdWriteStreamStop(); + set_viewport(x, row1, cx, 1); + stream_start(); + write_data(buf, cx); + stream_stop(); } } /* fill the remaining gap */ - lld_lcdSetViewPort(x, lines > 0 ? (y+gap) : y, cx, abslines); - lld_lcdWriteStreamStart(); + set_viewport(x, lines > 0 ? (y+gap) : y, cx, abslines); + stream_start(); gap = cx*abslines; - for(i = 0; i < gap; i++) lld_lcdWriteData(bgcolor); - lld_lcdWriteStreamStop(); - lld_lcdResetViewPort(); + for(i = 0; i < gap; i++) write_data(bgcolor); + stream_stop(); + reset_viewport(); + release_bus(); } #endif @@ -457,26 +516,26 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { return; switch((gdisp_orientation_t)value) { case GDISP_ROTATE_0: - lld_lcdWriteReg(0x0001,0x0127); - lld_lcdWriteReg(0x03, 0b0011); + write_reg(0x0001,0x0127); + write_reg(0x03, 0b0011); GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_90: - lld_lcdWriteReg(0x0001,0x0027); - lld_lcdWriteReg(0x0003, 0b1011); + write_reg(0x0001,0x0027); + write_reg(0x0003, 0b1011); GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_180: - lld_lcdWriteReg(0x0001,0x0127); - lld_lcdWriteReg(0x0003, 0b0000); + write_reg(0x0001,0x0127); + write_reg(0x0003, 0b0000); GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_270: - lld_lcdWriteReg(0x0001,0x0027); - lld_lcdWriteReg(0x0003, 0b1000); + write_reg(0x0001,0x0027); + write_reg(0x0003, 0b1000); GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; diff --git a/drivers/gdisp/S6D1121/gdisp_lld_board_example.h b/drivers/gdisp/S6D1121/gdisp_lld_board_example.h new file mode 100644 index 00000000..c47a6ed6 --- /dev/null +++ b/drivers/gdisp/S6D1121/gdisp_lld_board_example.h @@ -0,0 +1,125 @@ +/* + ChibiOS/RT - Copyright (C) 2012 + Joel Bodenmann aka Tectu + + 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 . +*/ + +/** + * @file drivers/gdisp/SSD1289/gdisp_lld_board_example.h + * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +/** + * @brief Initialise the board for the display. + * + * @notapi + */ +static __inline void init_board(void) { + /* Code here */ +#error "SSD1289: You must supply a definition for init_board for your board" +} + +/** + * @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) { + /* Code here */ +#error "SSD1289: You must supply a definition for setpin_reset for your board" +} + +/** + * @brief Set the lcd back-light level. + * + * @param[in] percent 0 to 100% + * + * @notapi + */ +static __inline void set_backlight(uint8_t percent) { + /* Code here */ +#error "SSD1289: You must supply a definition for set_backlight for your board" +} + +/** + * @brief Take exclusive control of the bus + * + * @notapi + */ +static __inline void acquire_bus(void) { +#error "SSD1289: You must supply a definition for acquire_bus for your board" +} + +/** + * @brief Release exclusive control of the bus + * + * @notapi + */ +static __inline void release_bus(void) { +#error "SSD1289: You must supply a definition for release_bus for your board" +} + +/** + * @brief Send data to the index register. + * + * @param[in] index The index register to set + * + * @notapi + */ +static __inline void write_index(uint16_t index) { + /* Code here */ +#error "SSD1289: You must supply a definition for write_index for your board" +} + +/** + * @brief Send data to the lcd. + * + * @param[in] data The data to send + * + * @notapi + */ +static __inline void write_data(uint16_t data) { + /* Code here */ +#error "SSD1289: You must supply a definition for write_data for your board" +} + +#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || 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) { + /* Code here */ +#error "SSD1289: You must supply a definition for read_data for your board" +} +#endif + +#endif /* _GDISP_LLD_BOARD_H */ +/** @} */ diff --git a/drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h b/drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h new file mode 100644 index 00000000..977405c6 --- /dev/null +++ b/drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h @@ -0,0 +1,94 @@ +/* + ChibiOS/RT - Copyright (C) 2012 + Joel Bodenmann aka Tectu + + 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 . +*/ + +/** + * @file drivers/gdisp/SSD1289/gdisp_lld_board_olimex_e407.h + * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */ +#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */ + +static __inline void init_board(void) { + int FSMC_Bank = 0; + + /* STM32F4 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 << 11) | (1 << 14) | (1 << 15), 0}; + + IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | + (1 << 13) | (1 << 14) | (1 << 15), 0}; + + palSetBusMode(&busD, PAL_MODE_ALTERNATE(12)); + palSetBusMode(&busE, PAL_MODE_ALTERNATE(12)); + + /* FSMC timing */ + FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16); + + /* Bank1 NOR/SRAM control register configuration */ + FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; +} + +static __inline void setpin_reset(bool_t state) { + (void)state; + + /* Nothing to do here */ +} + +static __inline void set_backlight(uint8_t percent) { + (void)percent; + + /* Nothing to do here */ +} + +static __inline void acquire_bus(void) { + /* Nothing to do here */ +} + +static __inline void release_bus(void) { + /* Nothing to do here */ +} + +static __inline void write_index(uint16_t index) { + GDISP_REG = index; +} + +static __inline void write_data(uint16_t data) { + GDISP_RAM = data; +} + +#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__) +static __inline uint16_t read_data(void) { + return GDISP_RAM; +} +#endif + +#endif /* _GDISP_LLD_BOARD_H */ +/** @} */ + diff --git a/drivers/gdisp/S6D1121/gdisp_lld_config.h b/drivers/gdisp/S6D1121/gdisp_lld_config.h index cc1b2907..95046946 100644 --- a/drivers/gdisp/S6D1121/gdisp_lld_config.h +++ b/drivers/gdisp/S6D1121/gdisp_lld_config.h @@ -20,7 +20,7 @@ /** * @file drivers/gdisp/S6D1121/gdisp_lld_config.h - * @brief GDISP Graphic Driver subsystem low level driver header for the S6d1121 display. + * @brief GDISP Graphic Driver subsystem low level driver header for the S6D1121 display. * * @addtogroup GDISP * @{ diff --git a/drivers/gdisp/S6D1121/readme.txt b/drivers/gdisp/S6D1121/readme.txt index 1ca9a6f0..b76b565f 100644 --- a/drivers/gdisp/S6D1121/readme.txt +++ b/drivers/gdisp/S6D1121/readme.txt @@ -3,13 +3,7 @@ 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) One (only) of: - #define GDISP_USE_GPIO - #define GDISP_USE_SPI - #define GDISP_USE_FSMC - d) All of the following (with appropriate values): - #define GDISP_SCREEN_WIDTH 320 - #define GDISP_SCREEN_HEIGHT 240 2. To your makefile add the following lines: include $(GFXLIB)/drivers/gdisp/S6D1121/gdisp_lld.mk + diff --git a/drivers/gdisp/S6D1121/s6d1121_lld.c.h b/drivers/gdisp/S6D1121/s6d1121_lld.c.h deleted file mode 100644 index b8f8078b..00000000 --- a/drivers/gdisp/S6D1121/s6d1121_lld.c.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - ChibiOS/GFX - Copyright (C) 2012 - Joel Bodenmann aka Tectu - - 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 . -*/ - -#ifndef S6D1121_H -#define S6D1121_H - -// I/O assignments -#define GDISP_BL_GPIO GPIOB -#define GDISP_BL_PIN 8 - -#define GDISP_CS_GPIO GPIOD -#define GDISP_CS_PIN 7 - -#define GDISP_RS_GPIO GPIOD -#define GDISP_RS_PIN 11 - -#define GDISP_RST_GPIO GPIOD -#define GDISP_RST_PIN 10 - -#define GDISP_RD_GPIO GPIOD -#define GDISP_RD_PIN 9 - -#define GDISP_WR_GPIO GPIOD -#define GDISP_WR_PIN 8 - -#define GDISP_D0_GPIO GPIOD -#define GDISP_D4_GPIO GPIOE - -/* all interfaces use RST via GPIO */ -/* TODO: option to disable RST; assumes RST is tied high */ -#define GDISP_RST_LOW palClearPad(GDISP_RST_GPIO, GDISP_RST_PIN) -#define GDISP_RST_HIGH palSetPad(GDISP_RST_GPIO, GDISP_RST_PIN) - -#define s6d1121_delay(n) halPolledDelay(MS2RTT(n)); - -#if defined(GDISP_USE_GPIO) - - #define GDISP_CS_LOW palClearPad(GDISP_CS_GPIO, GDISP_CS_PIN) - #define GDISP_CS_HIGH palSetPad(GDISP_CS_GPIO, GDISP_CS_PIN) - - #define GDISP_RS_LOW palClearPad(GDISP_RS_GPIO, GDISP_RS_PIN) - #define GDISP_RS_HIGH palSetPad(GDISP_RS_GPIO, GDISP_RS_PIN) - - #define GDISP_RD_LOW palClearPad(GDISP_RD_GPIO, GDISP_RD_PIN) - #define GDISP_RD_HIGH palSetPad(GDISP_RD_GPIO, GDISP_RD_PIN) - - #define GDISP_WR_LOW palClearPad(GDISP_WR_GPIO, GDISP_WR_PIN) - #define GDISP_WR_HIGH palSetPad(GDISP_WR_GPIO, GDISP_WR_PIN) - - #define GDISP_BL_LOW palClearPad(GDISP_BL_GPIO, GDISP_BL_PIN) - #define GDISP_BL_HIGH palSetPad(GDISP_BL_GPIO, GDISP_BL_PIN) - - - static inline void lld_lcddelay(void) { asm volatile ("nop"); asm volatile ("nop"); } - static inline void lld_lcdwrite(uint16_t db) { - GDISP_D4_GPIO->BSRR.W=((~db&0xFFF0)<<16)|(db&0xFFF0); - GDISP_D0_GPIO->BSRR.W=((~db&0x000F)<<16)|(db&0x000F); - GDISP_WR_LOW; - lld_lcddelay(); - GDISP_WR_HIGH; - } - static __inline uint16_t lld_lcdReadData(void) { - uint16_t value=0; - - GDISP_RS_HIGH; GDISP_WR_HIGH; GDISP_RD_LOW; - #ifndef STM32F4XX - // change pin mode to digital input - GDISP_DATA_PORT->CRH = 0x47444444; - GDISP_DATA_PORT->CRL = 0x47444444; - #endif - #ifndef STM32F4XX - // change pin mode back to digital output - GDISP_DATA_PORT->CRH = 0x33333333; - GDISP_DATA_PORT->CRL = 0x33333333; - #endif - GDISP_RD_HIGH; - return value; - } - static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { - uint16_t lcdRAM; - - GDISP_CS_LOW; GDISP_RS_LOW; - lld_lcdwrite(lcdReg); - GDISP_RS_HIGH; - lcdRAM = lld_lcdReadData(); - GDISP_CS_HIGH; - return lcdRAM; - } - static void lld_lcdWriteIndex(uint16_t lcdReg) { - GDISP_RS_LOW; - lld_lcdwrite(lcdReg); - GDISP_RS_HIGH; - } - static void lld_lcdWriteData(uint16_t lcdData) { - lld_lcdwrite(lcdData); - } - static void lld_lcdWriteReg(uint16_t lcdReg, uint16_t lcdRegValue) { - GDISP_CS_LOW; - lld_lcdWriteIndex(lcdReg); - lld_lcdWriteData(lcdRegValue); - GDISP_CS_HIGH; - } - static __inline void lld_lcdWriteStreamStart(void) { - GDISP_CS_LOW; - lld_lcdWriteIndex(0x0022); - } - static __inline void lld_lcdWriteStreamStop(void) { - GDISP_CS_HIGH; - } - static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { - uint16_t i; - - for(i = 0; i < size; i++) { lld_lcdwrite(buffer[i]); } - } - static __inline void lld_lcdReadStreamStart(void) { /* TODO */ } - static __inline void lld_lcdReadStreamStop(void) { /* TODO */ } - static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { - (void)buffer; - (void)size; - - /* TODO */ - } - -#elif defined(GDISP_USE_FSMC) - #define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */ - #define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */ - - static __inline void lld_lcdWriteIndex(uint16_t index) { GDISP_REG = index; } - static __inline void lld_lcdWriteData(uint16_t data) { GDISP_RAM = data; } - static __inline void lld_lcdWriteReg(uint16_t lcdReg,uint16_t lcdRegValue) { - GDISP_REG = lcdReg; - GDISP_RAM = lcdRegValue; - } - static __inline uint16_t lld_lcdReadData(void) { return (GDISP_RAM); } - static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { - GDISP_REG = lcdReg; - return GDISP_RAM; - } - static __inline void lld_lcdWriteStreamStart(void) { GDISP_REG = 0x0022; } - static __inline void lld_lcdWriteStreamStop(void) {} - static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) { - uint16_t i; - for(i = 0; i < size; i++) GDISP_RAM = buffer[i]; - } - static __inline void lld_lcdReadStreamStart(void) { GDISP_REG = 0x0022; } - static __inline void lld_lcdReadStreamStop(void) {} - static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) { - uint16_t i; - volatile uint16_t dummy; - - /* throw away first value read */ - dummy = GDISP_RAM; - for(i = 0; i < size; i++) buffer[i] = GDISP_RAM; - } - -#elif defined(GDISP_USE_SPI) - #error "gdispS6d1121: GDISP_USE_SPI not implemented yet" -#endif - -static void lld_lcdSetCursor(coord_t x, coord_t y) { - /* R20h - 8 bit - * R21h - 9 bit - */ - switch(GDISP.Orientation) { - case GDISP_ROTATE_0: - lld_lcdWriteReg(0x0020, x & 0x00FF); - lld_lcdWriteReg(0x0021, y & 0x01FF); - break; - case GDISP_ROTATE_90: - /* Note X has already been mirrored, so we do it directly */ - lld_lcdWriteReg(0x0020, y & 0x00FF); - lld_lcdWriteReg(0x0021, x & 0x01FF); - break; - case GDISP_ROTATE_180: - lld_lcdWriteReg(0x0020, (GDISP_SCREEN_WIDTH - 1 - x) & 0x00FF); - lld_lcdWriteReg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - y) & 0x01FF); - break; - case GDISP_ROTATE_270: - lld_lcdWriteReg(0x0020, (GDISP_SCREEN_WIDTH - 1 - y) & 0x00FF); - lld_lcdWriteReg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - x) & 0x01FF); - break; - } -} - -static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) { - /* HSA / HEA are 8 bit - * VSA / VEA are 9 bit - * use masks 0x00FF and 0x01FF to enforce this - */ - - switch(GDISP.Orientation) { - case GDISP_ROTATE_0: - lld_lcdWriteReg(0x46, (((x + cx - 1) << 8) & 0xFF00 ) | - (x & 0x00FF)); - - lld_lcdWriteReg(0x48, y & 0x01FF); - lld_lcdWriteReg(0x47, (y + cy - 1) & 0x01FF); - break; - case GDISP_ROTATE_90: - lld_lcdWriteReg(0x46, (((y + cy - 1) << 8) & 0xFF00) | - (y & 0x00FF)); - - lld_lcdWriteReg(0x48, x & 0x01FF); - lld_lcdWriteReg(0x47, (x + cx - 1) & 0x01FF); - break; - case GDISP_ROTATE_180: - lld_lcdWriteReg(0x46, (((GDISP_SCREEN_WIDTH - x - 1) & 0x00FF) << 8) | - ((GDISP_SCREEN_WIDTH - (x + cx)) & 0x00FF)); - lld_lcdWriteReg(0x48, (GDISP_SCREEN_HEIGHT - (y + cy)) & 0x01FF); - lld_lcdWriteReg(0x47, (GDISP_SCREEN_HEIGHT- y - 1) & 0x01FF); - break; - case GDISP_ROTATE_270: - lld_lcdWriteReg(0x46, (((GDISP_SCREEN_WIDTH - y - 1) & 0x00FF) << 8) | - ((GDISP_SCREEN_WIDTH - (y + cy)) & 0x00FF)); - lld_lcdWriteReg(0x48, (GDISP_SCREEN_HEIGHT - (x + cx)) & 0x01FF); - lld_lcdWriteReg(0x47, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF); - break; - } - - lld_lcdSetCursor(x, y); -} - -static void lld_lcdResetViewPort(void) { - switch(GDISP.Orientation) { - case GDISP_ROTATE_0: - case GDISP_ROTATE_180: - lld_lcdSetViewPort(0, 0, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT); - break; - case GDISP_ROTATE_90: - case GDISP_ROTATE_270: - lld_lcdSetViewPort(0, 0, GDISP_SCREEN_HEIGHT, GDISP_SCREEN_WIDTH); - break; - } -} - -#endif /* S6D1121_H */ - -- cgit v1.2.3