From 6107cd79180603660374c626da15e70ac4f26a5e Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Sat, 22 Jun 2013 03:09:45 +0200 Subject: [PATCH] Added RA8875 GDISP driver --- drivers/gdisp/RA8875/gdisp_lld.c | 460 ++++++++++++++++++ drivers/gdisp/RA8875/gdisp_lld.mk | 6 + drivers/gdisp/RA8875/gdisp_lld_board.h | 199 ++++++++ .../RA8875/gdisp_lld_board_example_fsmc.h | 181 +++++++ .../RA8875/gdisp_lld_board_example_gpio.h | 171 +++++++ drivers/gdisp/RA8875/gdisp_lld_config.h | 42 ++ drivers/gdisp/RA8875/gdisp_lld_panel.h | 74 +++ .../gdisp/RA8875/gdisp_lld_panel_example.h | 74 +++ drivers/gdisp/RA8875/ra8875.h | 18 + drivers/gdisp/RA8875/readme.txt | 38 ++ releases.txt | 1 + 11 files changed, 1264 insertions(+) create mode 100644 drivers/gdisp/RA8875/gdisp_lld.c create mode 100644 drivers/gdisp/RA8875/gdisp_lld.mk create mode 100644 drivers/gdisp/RA8875/gdisp_lld_board.h create mode 100644 drivers/gdisp/RA8875/gdisp_lld_board_example_fsmc.h create mode 100644 drivers/gdisp/RA8875/gdisp_lld_board_example_gpio.h create mode 100644 drivers/gdisp/RA8875/gdisp_lld_config.h create mode 100644 drivers/gdisp/RA8875/gdisp_lld_panel.h create mode 100644 drivers/gdisp/RA8875/gdisp_lld_panel_example.h create mode 100644 drivers/gdisp/RA8875/ra8875.h create mode 100644 drivers/gdisp/RA8875/readme.txt diff --git a/drivers/gdisp/RA8875/gdisp_lld.c b/drivers/gdisp/RA8875/gdisp_lld.c new file mode 100644 index 00000000..e04e5dba --- /dev/null +++ b/drivers/gdisp/RA8875/gdisp_lld.c @@ -0,0 +1,460 @@ +/* + * 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://chibios-gfx.com/license.html + */ + +/** + * @file drivers/gdisp/RA8875/gdisp_lld.c + * @brief GDISP Graphics Driver subsystem low level driver source. + * + * @addtogroup GDISP + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "gfx.h" + +#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/ + +/* Include the emulation code for things we don't support */ +#include "gdisp/lld/emulation.c" + +#include "ra8875.h" + +/* include the board abstraction */ +#include "gdisp_lld_board.h" + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + + +/* ---- Required Routines ---- */ +/* + The following 2 routines are required. + All other routines are optional. +*/ + +/** + * @brief Low level GDISP driver initialisation. + * @return TRUE if successful, FALSE on error. + * + * @notapi + */ +bool_t gdisp_lld_init(void) { + /* Initialise the display */ + init_board(); + + /* soft reset */ + write_index(0x01); + write_data(0x01); + write_data(0x00); + chThdSleepMilliseconds(1); + + /* Driver PLL config 480x272*/ + write_index(0x88); + write_data(0x08); + chThdSleepMilliseconds(1); + write_index(0x89); + write_data(0x02); + chThdSleepMilliseconds(1); + + write_index(0x10); //SYSR bit[4:3]=00 256 color bit[2:1]= 00 8bit MPU interface + write_data(0x0F); // if 16bit MCU interface and 65k color display + + write_index(0x04); //set PCLK invers + write_data(0x82); + chThdSleepMilliseconds(1); + + //Horizontal set + write_index(0x14); //HDWR//Horizontal Display Width Setting Bit[6:0] + write_data(0x3B);//Horizontal display width(pixels) = (HDWR + 1)*8 + write_index(0x15); //Horizontal Non-Display Period Fine Tuning Option Register (HNDFTR) + write_data(0x00);//Horizontal Non-Display Period Fine Tuning(HNDFT) [3:0] + write_index(0x16); //HNDR//Horizontal Non-Display Period Bit[4:0] + write_data(0x01);//Horizontal Non-Display Period (pixels) = (HNDR + 1)*8 + write_index(0x17); //HSTR//HSYNC Start Position[4:0] + write_data(0x00);//HSYNC Start Position(PCLK) = (HSTR + 1)*8 + write_index(0x18); //HPWR//HSYNC Polarity ,The period width of HSYNC. + write_data(0x05);//HSYNC Width [4:0] HSYNC Pulse width(PCLK) = (HPWR + 1)*8 + + //Vertical set + write_index(0x19); //VDHR0 //Vertical Display Height Bit [7:0] + write_data(0x0f); //Vertical pixels = VDHR + 1 + write_index(0x1a); //VDHR1 //Vertical Display Height Bit [8] + write_data(0x01); //Vertical pixels = VDHR + 1 + write_index(0x1b); //VNDR0 //Vertical Non-Display Period Bit [7:0] + write_data(0x02); //VSYNC Start Position(PCLK) = (VSTR + 1) + write_index(0x1c); //VNDR1 //Vertical Non-Display Period Bit [8] + write_data(0x00); //Vertical Non-Display area = (VNDR + 1) + write_index(0x1d); //VSTR0 //VSYNC Start Position[7:0] + write_data(0x07);//VSYNC Start Position(PCLK) = (VSTR + 1) + write_index(0x1e); //VSTR1 //VSYNC Start Position[8] + write_data(0x00);//VSYNC Start Position(PCLK) = (VSTR + 1) + write_index(0x1f); //VPWR //VSYNC Polarity ,VSYNC Pulse Width[6:0] + write_data(0x09); //VSYNC Pulse Width(PCLK) = (VPWR + 1) + + //Active window set + //setting active window X + write_index(0x30); //Horizontal Start Point 0 of Active Window (HSAW0) + write_data(0x00); //Horizontal Start Point of Active Window [7:0] + write_index(0x31); //Horizontal Start Point 1 of Active Window (HSAW1) + write_data(0x00); //Horizontal Start Point of Active Window [9:8] + write_index(0x34); //Horizontal End Point 0 of Active Window (HEAW0) + write_data(0xDF); //Horizontal End Point of Active Window [7:0] + write_index(0x35); //Horizontal End Point 1 of Active Window (HEAW1) + write_data(0x01); //Horizontal End Point of Active Window [9:8] + + //setting active window Y + write_index(0x32); //Vertical Start Point 0 of Active Window (VSAW0) + write_data(0x00); //Vertical Start Point of Active Window [7:0] + write_index(0x33); //Vertical Start Point 1 of Active Window (VSAW1) + write_data(0x00); //Vertical Start Point of Active Window [8] + write_index(0x36); //Vertical End Point of Active Window 0 (VEAW0) + write_data(0x0F); //Vertical End Point of Active Window [7:0] + write_index(0x37); //Vertical End Point of Active Window 1 (VEAW1) + write_data(0x01); //Vertical End Point of Active Window [8] + + // Display ON + write_index(0x01); //PWRR + write_data(0x80); + + // GPO0 DISP high + write_index(0x13); //GPO + write_data(0x01); + + set_backlight(0x80); //set to 90% brightness + + post_init_board(); + + /* Initialise the GDISP structure to match */ + GDISP.Width = GDISP_SCREEN_WIDTH; + GDISP.Height = GDISP_SCREEN_HEIGHT; + GDISP.Orientation = GDISP_ROTATE_0; + GDISP.Powermode = powerOn; + GDISP.Backlight = 100; + GDISP.Contrast = 50; + #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP + GDISP.clipx0 = 0; + GDISP.clipy0 = 0; + GDISP.clipx1 = GDISP.Width; + GDISP.clipy1 = GDISP.Height; + #endif + + return TRUE; +} + +void gdisp_lld_setwindow(coord_t x0, coord_t y0, coord_t x1, coord_t y1) { + /* We don't need to validate here as the LLD routines will validate first. + * + * #if GDISP_NEED_VALIDATION + * if (x0 >= GDISP.Width || y0 >= GDISP.Height || x0 < 0 || y0 < 0) return; + * else if (x1 >= GDISP.Width || y1 >= GDISP.Height || y1 < 0 || y2 < 0) return; + * #endif + */ + + //setting active window X + write_index(0x30); //HSAW0 + write_data(x0); + write_index(0x31); //HSAW1 + write_data(x0>>8); + + write_index(0x34); //HEAW0 + write_data(x1); + write_index(0x35); //HEAW1 + write_data(x1>>8); + + //setting active window Y + write_index(0x32); //VSAW0 + write_data(y0); + write_index(0x33); //VSAW1 + write_data(y0>>8); + + write_index(0x36); //VEAW0 + write_data(y1); + write_index(0x37); //VEAW1 + write_data(y1>>8); + + write_index(0x46); + write_data(x0); + write_index(0x47); + write_data(x0>>8); + + write_index(0x48); + write_data(y0); + write_index(0x49); + write_data(y0>>8); +} + +/** + * @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 + + gdisp_lld_setwindow(x, y, x, y); + write_index(RA8875_WRITE_MEMORY_START); + write_data(color); +} + +/* ---- Optional Routines ---- */ + +#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) { + uint32_t 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; + + gdisp_lld_setwindow(x, y, x+cx-1, y+cy-1); + write_index(RA8875_WRITE_MEMORY_START); + + #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + uint8_t i; + dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color); + dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); + for (i = area/65535; i; i--) { + dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + } + dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + #else + uint32_t index; + for(index = 0; index < area; index++) + write_data(color); + #endif //#ifdef GDISP_USE_DMA +} +#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) { + + #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 + + gdisp_lld_setwindow(x, y, x+cx-1, y+cy-1); + write_index(RA8875_WRITE_MEMORY_START); + + buffer += srcx + srcy * srccx; + + #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + uint32_t area = cx*cy; + uint8_t i; + dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer); + dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); + for (i = area/65535; i; i--) { + dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + } + dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535); + dmaStreamEnable(GDISP_DMA_STREAM); + dmaWaitCompletion(GDISP_DMA_STREAM); + #else + coord_t endx, endy; + uint32_t lg; + endx = srcx + cx; + endy = y + cy; + lg = srccx - cx; + for(; y < endy; y++, buffer += lg) + for(x=srcx; x < endx; x++) + write_data(*buffer++); + #endif //#ifdef GDISP_USE_DMA + } +#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) { + #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 + /* NOT IMPLEMENTED YET */ + + /* + uint16_t size = x1 - x0 ; + + write_index(SSD1963_SET_SCROLL_AREA); + write_data((x0 >> 8) & 0xFF); + write_data((x0 >> 0) & 0xFF); + write_data((size >> 8) & 0xFF); + write_data((size >> 0) & 0xFF); + write_data(((lcd_height-x1) >> 8) & 0xFF); + write_data(((lcd_height-x1) >> 0) & 0xFF); + + write_index(SSD1963_SET_SCROLL_START); + write_data((lines >> 8) & 0xFF); + write_data((lines >> 0) & 0xFF); + */ + } + +#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. + * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100. + * GDISP_CONTROL_LLD - Low level driver control constants start at + * this value. + * + * @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) { + /* NOT IMPLEMENTED YET */ + switch(what) { + case GDISP_CONTROL_POWER: + if (GDISP.Powermode == (gdisp_powermode_t)value) + return; + switch((gdisp_powermode_t)value) { + case powerOff: + write_index(SSD1963_EXIT_SLEEP_MODE); // leave sleep mode + chThdSleepMilliseconds(5); + write_index(SSD1963_SET_DISPLAY_OFF); + write_index(SSD1963_SET_DEEP_SLEEP); // enter deep sleep mode + break; + case powerOn: + read_reg(0x0000); chThdSleepMilliseconds(5); // 2x Dummy reads to wake up from deep sleep + read_reg(0x0000); chThdSleepMilliseconds(5); + if (GDISP.Powermode != powerSleep) + gdisp_lld_init(); + write_index(SSD1963_SET_DISPLAY_ON); + + break; + case powerSleep: + write_index(SSD1963_SET_DISPLAY_OFF); + write_index(SSD1963_ENTER_SLEEP_MODE); // enter sleep mode + chThdSleepMilliseconds(5); + break; + default: + return; + } + GDISP.Powermode = (gdisp_powermode_t)value; + return; + case GDISP_CONTROL_ORIENTATION: + if (GDISP.Orientation == (gdisp_orientation_t)value) + return; + switch((gdisp_orientation_t)value) { + case GDISP_ROTATE_0: + /* Code here */ + GDISP.Height = GDISP_SCREEN_HEIGHT; + GDISP.Width = GDISP_SCREEN_WIDTH; + break; + case GDISP_ROTATE_90: + /* Code here */ + GDISP.Height = GDISP_SCREEN_WIDTH; + GDISP.Width = GDISP_SCREEN_HEIGHT; + break; + case GDISP_ROTATE_180: + /* Code here */ + GDISP.Height = GDISP_SCREEN_HEIGHT; + GDISP.Width = GDISP_SCREEN_WIDTH; + break; + case GDISP_ROTATE_270: + /* Code here */ + 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: + gdisp_lld_bg_dimmer(54 + ((uint8_t)value) << 1);//turn 0..100% in 54..255 + return; +/* + case GDISP_CONTROL_CONTRAST: +*/ + } + } +#endif + +#endif /* GFX_USE_GDISP */ +/** @} */ + diff --git a/drivers/gdisp/RA8875/gdisp_lld.mk b/drivers/gdisp/RA8875/gdisp_lld.mk new file mode 100644 index 00000000..471b7e83 --- /dev/null +++ b/drivers/gdisp/RA8875/gdisp_lld.mk @@ -0,0 +1,6 @@ +# List the required driver. +GFXSRC += $(GFXLIB)/drivers/gdisp/RA8875/gdisp_lld.c + +# Required include directories +GFXINC += $(GFXLIB)/drivers/gdisp/RA8875 + diff --git a/drivers/gdisp/RA8875/gdisp_lld_board.h b/drivers/gdisp/RA8875/gdisp_lld_board.h new file mode 100644 index 00000000..c8370020 --- /dev/null +++ b/drivers/gdisp/RA8875/gdisp_lld_board.h @@ -0,0 +1,199 @@ +/* + * 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://chibios-gfx.com/license.html + */ + +/** + * @file drivers/gdisp/SSD1289/gdisp_lld_board_example_fsmc.h + * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +#if defined(GDISP_USE_GPIO) + #define Set_CS palSetPad(GDISP_CMD_PORT, GDISP_CS); + #define Clr_CS palClearPad(GDISP_CMD_PORT, GDISP_CS); + #define Set_RS palSetPad(GDISP_CMD_PORT, GDISP_RS); + #define Clr_RS palClearPad(GDISP_CMD_PORT, GDISP_RS); + #define Set_WR palSetPad(GDISP_CMD_PORT, GDISP_WR); + #define Clr_WR palClearPad(GDISP_CMD_PORT, GDISP_WR); + #define Set_RD palSetPad(GDISP_CMD_PORT, GDISP_RD); + #define Clr_RD palClearPad(GDISP_CMD_PORT, GDISP_RD); +#endif + +#if defined(GDISP_USE_FSMC) + /* Using FSMC A16 as RS */ + #define GDISP_RAM (*((volatile uint16_t *) 0x68000000)) /* RS = 0 */ + #define GDISP_REG (*((volatile uint16_t *) 0x68020000)) /* RS = 1 */ +#endif + +/** + * @brief Send data to the index register. + * + * @param[in] index The index register to set + * + * @notapi + */ +static inline void write_index(uint16_t index) { GDISP_REG = index; } + +/** + * @brief Send data to the lcd. + * + * @param[in] data The data to send + * + * @notapi + */ +static inline void write_data(uint16_t data) { GDISP_RAM = data; } + +/** + * @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) { return GDISP_RAM; } + +/** + * @brief Initialise the board for the display. + * @notes Performs the following functions: + * 1. initialise the io port used by your display + * 2. initialise the reset pin (initial state not-in-reset) + * 3. initialise the chip select pin (initial state not-active) + * 4. initialise the backlight pin (initial state back-light off) + * + * @notapi + */ +static inline void init_board(void) { + const unsigned char FSMC_Bank = 4; + + #if defined(STM32F1XX) || defined(STM32F3XX) + /* FSMC setup for F1/F3 */ + rccEnableAHB(RCC_AHBENR_FSMCEN, 0); + + #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + #error "DMA not implemented for F1/F3 Devices" + #endif + #elif defined(STM32F4XX) || defined(STM32F2XX) + /* STM32F2-F4 FSMC init */ + rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); + + #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) chSysHalt(); + dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM); + dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); + #endif + #else + #error "FSMC not implemented for this device" + #endif + + /* set pins to FSMC mode */ + IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (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}; + + IOBus busG = {GPIOG, (1 << 10), 0}; + + palSetBusMode(&busD, PAL_MODE_ALTERNATE(12)); + palSetBusMode(&busE, PAL_MODE_ALTERNATE(12)); + palSetBusMode(&busG, PAL_MODE_ALTERNATE(12)); + + /* 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; +} + +static inline void post_init_board(void) { + const unsigned char FSMC_Bank = 2; + /* FSMC delay reduced as the controller now runs at full speed */ + FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ; + FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; +} + +/** + * @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) { + (void) state; + /* Nothing to do here */ +} + +/** + * @brief Set the lcd back-light level. + * + * @param[in] percent 0 to 100% + * + * @notapi + */ +static inline void set_backlight(uint8_t percent) { + + //duty_cycle is 00..FF + //Work in progress: the RA8875 has a built-in PWM, its output can + //be used by a Dynamic Background Control or by a host (user) + + uint8_t temp, temp1; + // Enable PWM1 + write_index(0x8a);//MCLR + temp = read_data(); + temp |= 1<<7 ; + write_data(temp); + + // PWM1 function select + write_index(0x8a);//MCLR + temp = read_data(); + temp &= ~(1<<4); + write_data(temp); + + // PWM1 Clock ratio + temp1= 0x0b&0x0f; + write_index(0x8a);//MCLR + temp = read_data(); + temp &= 0xf0; + temp |= temp1 ; + write_data(temp); + + // Write duty cycle + write_index(0x8b);//PTNO + write_data(percent); + // PWM1 duty cycle +} + +/** + * @brief Take exclusive control of the bus + * + * @notapi + */ +static inline void acquire_bus(void) { + /* Nothing to do here */ +} + +/** + * @brief Release exclusive control of the bus + * + * @notapi + */ +static inline void release_bus(void) { + /* Nothing to do here */ +} + +#endif /* _GDISP_LLD_BOARD_H */ +/** @} */ diff --git a/drivers/gdisp/RA8875/gdisp_lld_board_example_fsmc.h b/drivers/gdisp/RA8875/gdisp_lld_board_example_fsmc.h new file mode 100644 index 00000000..f16fbfc7 --- /dev/null +++ b/drivers/gdisp/RA8875/gdisp_lld_board_example_fsmc.h @@ -0,0 +1,181 @@ +/* + * 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://chibios-gfx.com/license.html + */ + +/** + * @file drivers/gdisp/SSD1289/gdisp_lld_board_example_fsmc.h + * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +#if defined(GDISP_USE_GPIO) + #define Set_CS palSetPad(GDISP_CMD_PORT, GDISP_CS); + #define Clr_CS palClearPad(GDISP_CMD_PORT, GDISP_CS); + #define Set_RS palSetPad(GDISP_CMD_PORT, GDISP_RS); + #define Clr_RS palClearPad(GDISP_CMD_PORT, GDISP_RS); + #define Set_WR palSetPad(GDISP_CMD_PORT, GDISP_WR); + #define Clr_WR palClearPad(GDISP_CMD_PORT, GDISP_WR); + #define Set_RD palSetPad(GDISP_CMD_PORT, GDISP_RD); + #define Clr_RD palClearPad(GDISP_CMD_PORT, GDISP_RD); +#endif + +#if defined(GDISP_USE_FSMC) + /* Using FSMC A16 as RS */ + #define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */ + #define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */ +#endif + +/** + * @brief Send data to the index register. + * + * @param[in] index The index register to set + * + * @notapi + */ +static inline void write_index(uint16_t index) { GDISP_REG = index; } + +/** + * @brief Send data to the lcd. + * + * @param[in] data The data to send + * + * @notapi + */ +static inline void write_data(uint16_t data) { GDISP_RAM = data; } + +/** + * @brief Initialise the board for the display. + * @notes Performs the following functions: + * 1. initialise the io port used by your display + * 2. initialise the reset pin (initial state not-in-reset) + * 3. initialise the chip select pin (initial state not-active) + * 4. initialise the backlight pin (initial state back-light off) + * + * @notapi + */ +static inline void init_board(void) { + const unsigned char FSMC_Bank = 0; + + #if defined(STM32F1XX) || defined(STM32F3XX) + /* FSMC setup for F1/F3 */ + rccEnableAHB(RCC_AHBENR_FSMCEN, 0); + + #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + #error "DMA not implemented for F1/F3 Devices" + #endif + #elif defined(STM32F4XX) || defined(STM32F2XX) + /* STM32F2-F4 FSMC init */ + rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); + + #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) + if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) chSysHalt(); + dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM); + dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); + #endif + #else + #error "FSMC not implemented for this device" + #endif + + /* 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] = (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; +} + +static inline void post_init_board(void) { + const unsigned char FSMC_Bank = 0; + /* FSMC delay reduced as the controller now runs at full speed */ + FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ; + FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; +} + +/** + * @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) { + (void) state; + /* Nothing to do here */ +} + +/** + * @brief Set the lcd back-light level. + * + * @param[in] percent 0 to 100% + * + * @notapi + */ +static inline void set_backlight(uint8_t percent) { + //duty_cycle is 00..FF + //Work in progress: the SSD1963 has a built-in PWM, its output can + //be used by a Dynamic Background Control or by a host (user) + //Check your LCD's hardware, the PWM connection is default left open and instead + //connected to a LED connection on the breakout board + write_index(SSD1963_SET_PWM_CONF);//set PWM for BackLight + write_data(0x0001); + write_data(percent & 0x00FF); + write_data(0x0001);//controlled by host (not DBC), enabled + write_data(0x00FF); + write_data(0x0060);//don't let it go too dark, avoid a useless LCD + write_data(0x000F);//prescaler ??? +} + +/** + * @brief Take exclusive control of the bus + * + * @notapi + */ +static inline void acquire_bus(void) { + /* Nothing to do here */ +} + +/** + * @brief Release exclusive control of the bus + * + * @notapi + */ +static inline void release_bus(void) { + /* Nothing to do here */ +} + +#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) { return GDISP_RAM; } +#endif + +#endif /* _GDISP_LLD_BOARD_H */ +/** @} */ + diff --git a/drivers/gdisp/RA8875/gdisp_lld_board_example_gpio.h b/drivers/gdisp/RA8875/gdisp_lld_board_example_gpio.h new file mode 100644 index 00000000..af879520 --- /dev/null +++ b/drivers/gdisp/RA8875/gdisp_lld_board_example_gpio.h @@ -0,0 +1,171 @@ +/* + * 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://chibios-gfx.com/license.html + */ + +/** + * @file drivers/gdisp/SSD1963/gdisp_lld_board_example_gpio.h + * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +#if defined(GDISP_USE_GPIO) + #define Set_CS palSetPad(GDISP_CMD_PORT, GDISP_CS); + #define Clr_CS palClearPad(GDISP_CMD_PORT, GDISP_CS); + #define Set_RS palSetPad(GDISP_CMD_PORT, GDISP_RS); + #define Clr_RS palClearPad(GDISP_CMD_PORT, GDISP_RS); + #define Set_WR palSetPad(GDISP_CMD_PORT, GDISP_WR); + #define Clr_WR palClearPad(GDISP_CMD_PORT, GDISP_WR); + #define Set_RD palSetPad(GDISP_CMD_PORT, GDISP_RD); + #define Clr_RD palClearPad(GDISP_CMD_PORT, GDISP_RD); +#endif + +#if defined(GDISP_USE_FSMC) + /* Using FSMC A16 as RS */ + #define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */ + #define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */ +#endif + +/** + * @brief Send data to the index register. + * + * @param[in] index The index register to set + * + * @notapi + */ +static inline void write_index(uint16_t index) { + Set_CS; Set_RS; Set_WR; Clr_RD; + palWritePort(GDISP_DATA_PORT, index); + Clr_CS; +} + +/** + * @brief Send data to the lcd. + * + * @param[in] data The data to send + * + * @notapi + */ +static inline void write_data(uint16_t data) { + Set_CS; Clr_RS; Set_WR; Clr_RD; + palWritePort(GDISP_DATA_PORT, data); + Clr_CS; +} + +/** + * @brief Initialise the board for the display. + * + * @notapi + */ +static inline void init_board(void) { + + IOBus busCMD = {GDISP_CMD_PORT, (1 << GDISP_CS) | (1 << GDISP_RS) | (1 << GDISP_WR) | (1 << GDISP_RD), 0}; + IOBus busDATA = {GDISP_CMD_PORT, 0xFFFFF, 0}; + palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL); + palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL); +} + +static inline void post_init_board(void) { + /* Nothing to do here */ +} + +/** + * @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) { + +} + +/** + * @brief Set the lcd back-light level. + * + * @param[in] percent 0 to 100% + * + * @notapi + */ +static inline void set_backlight(uint8_t percent) { + //duty_cycle is 00..FF + //Work in progress: the SSD1963 has a built-in PWM, its output can + //be used by a Dynamic Background Control or by a host (user) + //Check your LCD's hardware, the PWM connection is default left open and instead + //connected to a LED connection on the breakout board + write_index(SSD1963_SET_PWM_CONF);//set PWM for BackLight + write_data(0x0001); + write_data(percent & 0x00FF); + write_data(0x0001);//controlled by host (not DBC), enabled + write_data(0x00FF); + write_data(0x0060);//don't let it go too dark, avoid a useless LCD + write_data(0x000F);//prescaler ??? +} + +/** + * @brief Take exclusive control of the bus + * + * @notapi + */ +static inline void acquire_bus(void) { + /* Nothing to do here */ +} + +/** + * @brief Release exclusive control of the bus + * + * @notapi + */ +static inline void release_bus(void) { + /* Nothing to do here */ +} + +__inline void write_stream(uint16_t *buffer, uint16_t size) { + uint16_t i; + Set_CS; Clr_RS; Set_WR; Clr_RD; + for(i = 0; i < size; i++) { + Set_WR; + palWritePort(GDISP_DATA_PORT, buffer[i]); + Clr_WR; + } + Clr_CS; +} + +__inline void read_stream(uint16_t *buffer, size_t size) { + uint16_t i; + Set_CS; Clr_RS; Clr_WR; Set_RD; + for(i = 0; i < size; i++) { + Set_RD; + buffer[i] = palReadPort(GDISP_DATA_PORT); + Clr_RD; + } +} + +#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) { + Set_CS; Clr_RS; Clr_WR; Set_RD; + uint16_t data = palReadPort(GDISP_DATA_PORT); + Clr_CS; + return data; +} +#endif + +#endif /* _GDISP_LLD_BOARD_H */ +/** @} */ + diff --git a/drivers/gdisp/RA8875/gdisp_lld_config.h b/drivers/gdisp/RA8875/gdisp_lld_config.h new file mode 100644 index 00000000..315ab177 --- /dev/null +++ b/drivers/gdisp/RA8875/gdisp_lld_config.h @@ -0,0 +1,42 @@ +/* + * 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://chibios-gfx.com/license.html + */ + +/** + * @file drivers/gdisp/SSD1963/gdisp_lld_config.h + * @brief GDISP Graphic Driver subsystem low level driver header. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +#define GDISP_DRIVER_NAME "RA8875" +#define GDISP_LLD(x) gdisp_lld_##x##_RA8875 + +#define GDISP_HARDWARE_FILLS TRUE +#define GDISP_HARDWARE_BITFILLS TRUE +#define GDISP_HARDWARE_READPIXEL TRUE + +/* Maybe someday soon */ +#define GDISP_HARDWARE_SCROLL FALSE +#define GDISP_HARDWARE_CONTROL FALSE + +#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ +/** @} */ + diff --git a/drivers/gdisp/RA8875/gdisp_lld_panel.h b/drivers/gdisp/RA8875/gdisp_lld_panel.h new file mode 100644 index 00000000..b6c4e4c8 --- /dev/null +++ b/drivers/gdisp/RA8875/gdisp_lld_panel.h @@ -0,0 +1,74 @@ +/* + * 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/SSD1963/gdisp_lld_panel_example.h + * @brief TFT LCD panel properties. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_PANEL_H +#define _GDISP_LLD_PANEL_H + +/* LCD panel specs */ + +/* The timings need to follow the datasheet for your particular TFT/LCD screen (the actual screen, not the controller) +*** Datasheets normally use a specific set of timings and acronyms, their value refers to the number of pixel clocks +** Non-display periods refer to pulses/timings that occur before or after the timings that actually put pixels on the screen +** Display periods refer to pulses/timings that directly put pixels on the screen +HDP: Horizontal Display Period, normally the width - 1 +HT: Horizontal Total period (display + non-display) +HPS: non-display period between the start of the horizontal sync (LLINE) signal and the first display data +LPS: horizontal sync pulse (LLINE) start location in pixel clocks +HPW: Horizontal sync Pulse Width +VDP: Vertical Display period, normally height - 1 +VT: Vertical Total period (display + non-display) +VPS: non-display period in lines between the start of the frame and the first display data in number of lines +FPS: vertical sync pulse (LFRAME) start location in lines. +VPW: Vertical sync Pulse Width + +*** Here's how to convert them: +HPS = SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH +HT - HPS = GDISP_SCREEN_WIDTH + SCREEN_HSYNC_FRONT_PORCH +=> SCREEN_HSYNC_FRONT_PORCH = ( HT - HPS ) - GDISP_SCREEN_WIDTH + SCREEN_HSYNC_PULSE = HPW + SCREEN_HSYNC_BACK_PORCH = HPS - HPW + SCREEN_HSYNC_PERIOD = HT + +VPS = SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH +VT - VPS = GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_FRONT_PORCH +=> SCREEN_VSYNC_FRONT_PORCH = ( VT - VPS ) - GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_PULSE = VPW + SCREEN_VSYNC_BACK_PORCH = VPS - LPS + SCREEN_VSYNC_PERIOD = VT +*/ + +#define SCREEN_FPS 60ULL + +//The following values are for a 4.3" TFT LCD + +#define GDISP_SCREEN_WIDTH 480 +#define GDISP_SCREEN_HEIGHT 272 + +#define SCREEN_HSYNC_BACK_PORCH 2 +#define SCREEN_HSYNC_FRONT_PORCH 2 +#define SCREEN_HSYNC_PULSE 41 + +#define SCREEN_VSYNC_BACK_PORCH 2 +#define SCREEN_VSYNC_FRONT_PORCH 2 +#define SCREEN_VSYNC_PULSE 10 + +#define SCREEN_HSYNC_PERIOD (SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH + GDISP_SCREEN_WIDTH + SCREEN_HSYNC_FRONT_PORCH) +#define SCREEN_VSYNC_PERIOD (SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH + GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_FRONT_PORCH) + +#define SCREEN_PCLK (SCREEN_HSYNC_PERIOD * SCREEN_VSYNC_PERIOD * SCREEN_FPS) +#define GDISP_FPR ((SCREEN_PCLK * 1048576)/100000000) + +#endif +/** @} */ diff --git a/drivers/gdisp/RA8875/gdisp_lld_panel_example.h b/drivers/gdisp/RA8875/gdisp_lld_panel_example.h new file mode 100644 index 00000000..b6c4e4c8 --- /dev/null +++ b/drivers/gdisp/RA8875/gdisp_lld_panel_example.h @@ -0,0 +1,74 @@ +/* + * 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/SSD1963/gdisp_lld_panel_example.h + * @brief TFT LCD panel properties. + * + * @addtogroup GDISP + * @{ + */ + +#ifndef _GDISP_LLD_PANEL_H +#define _GDISP_LLD_PANEL_H + +/* LCD panel specs */ + +/* The timings need to follow the datasheet for your particular TFT/LCD screen (the actual screen, not the controller) +*** Datasheets normally use a specific set of timings and acronyms, their value refers to the number of pixel clocks +** Non-display periods refer to pulses/timings that occur before or after the timings that actually put pixels on the screen +** Display periods refer to pulses/timings that directly put pixels on the screen +HDP: Horizontal Display Period, normally the width - 1 +HT: Horizontal Total period (display + non-display) +HPS: non-display period between the start of the horizontal sync (LLINE) signal and the first display data +LPS: horizontal sync pulse (LLINE) start location in pixel clocks +HPW: Horizontal sync Pulse Width +VDP: Vertical Display period, normally height - 1 +VT: Vertical Total period (display + non-display) +VPS: non-display period in lines between the start of the frame and the first display data in number of lines +FPS: vertical sync pulse (LFRAME) start location in lines. +VPW: Vertical sync Pulse Width + +*** Here's how to convert them: +HPS = SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH +HT - HPS = GDISP_SCREEN_WIDTH + SCREEN_HSYNC_FRONT_PORCH +=> SCREEN_HSYNC_FRONT_PORCH = ( HT - HPS ) - GDISP_SCREEN_WIDTH + SCREEN_HSYNC_PULSE = HPW + SCREEN_HSYNC_BACK_PORCH = HPS - HPW + SCREEN_HSYNC_PERIOD = HT + +VPS = SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH +VT - VPS = GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_FRONT_PORCH +=> SCREEN_VSYNC_FRONT_PORCH = ( VT - VPS ) - GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_PULSE = VPW + SCREEN_VSYNC_BACK_PORCH = VPS - LPS + SCREEN_VSYNC_PERIOD = VT +*/ + +#define SCREEN_FPS 60ULL + +//The following values are for a 4.3" TFT LCD + +#define GDISP_SCREEN_WIDTH 480 +#define GDISP_SCREEN_HEIGHT 272 + +#define SCREEN_HSYNC_BACK_PORCH 2 +#define SCREEN_HSYNC_FRONT_PORCH 2 +#define SCREEN_HSYNC_PULSE 41 + +#define SCREEN_VSYNC_BACK_PORCH 2 +#define SCREEN_VSYNC_FRONT_PORCH 2 +#define SCREEN_VSYNC_PULSE 10 + +#define SCREEN_HSYNC_PERIOD (SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH + GDISP_SCREEN_WIDTH + SCREEN_HSYNC_FRONT_PORCH) +#define SCREEN_VSYNC_PERIOD (SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH + GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_FRONT_PORCH) + +#define SCREEN_PCLK (SCREEN_HSYNC_PERIOD * SCREEN_VSYNC_PERIOD * SCREEN_FPS) +#define GDISP_FPR ((SCREEN_PCLK * 1048576)/100000000) + +#endif +/** @} */ diff --git a/drivers/gdisp/RA8875/ra8875.h b/drivers/gdisp/RA8875/ra8875.h new file mode 100644 index 00000000..7c25cf42 --- /dev/null +++ b/drivers/gdisp/RA8875/ra8875.h @@ -0,0 +1,18 @@ +/* + * 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://chibios-gfx.com/license.html + */ + +#ifndef RA8875_H +#define RA8875_H + +#define mHIGH(x) (x >> 8) +#define mLOW(x) (x & 0xFF) + +#define RA8875_WRITE_MEMORY_START 0x0002 +#define RA8875_READ_MEMORY_START 0x0002 + +#endif + diff --git a/drivers/gdisp/RA8875/readme.txt b/drivers/gdisp/RA8875/readme.txt new file mode 100644 index 00000000..ff4222b3 --- /dev/null +++ b/drivers/gdisp/RA8875/readme.txt @@ -0,0 +1,38 @@ +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: #define GDISP_NEED_MULTITHREAD TRUE + c) One (only) of: + #define GDISP_USE_GPIO + #define GDISP_USE_FSMC + d) If you want to use DMA (only works with FSMC): + #define GDISP_USE_DMA + #define GDISP_DMA_STREAM STM32_DMA2_STREAM6 //You can change the DMA channel according to your needs + +2. Edit gdisp_lld_panel.h with your panel properties + +3. To your makefile add the following lines: + include $(GFXLIB)/drivers/gdisp/RA8875/gdisp_lld.mk + + +Example FSMC config with DMA: + +#define GDISP_SCREEN_WIDTH 480 +#define GDISP_SCREEN_HEIGHT 272 + +#define GDISP_USE_FSMC + +#define GDISP_USE_DMA +#define GDISP_DMA_STREAM STM32_DMA2_STREAM6 + +#if defined(GDISP_USE_GPIO) + + #define GDISP_CMD_PORT GPIOC + #define GDISP_DATA_PORT GPIOD + + #define GDISP_CS 0 + #define GDISP_RS 1 + #define GDISP_WR 2 + #define GDISP_RD 3 +#endif diff --git a/releases.txt b/releases.txt index 86463cd3..5878daf3 100644 --- a/releases.txt +++ b/releases.txt @@ -35,6 +35,7 @@ FEATURE: Added HX8347D driver by user 'Eddie' FEATURE: Added enhanced notepad demo by user 'Abhishek' FEATURE: Added GOS module (including sub modules such as GQUEUE) FEATURE: Added some functionalities to the TDISP module by user 'Frysk' +FEATURE: Added RA8875 GDISP driver *** changes after 1.4 ***