Hi Ralph,
That code snippet just sets up the bus controller to use the CS RD/WR ADDR & Data lines to talk to the controller.
You will still need to initialize the external LCD controller and also interface to GuiX to copy the frame buffer out to the LCD.
Here is an example of a driver for a NewHaven display module that uses the ST77895 controller.
This driver uses DMA to copy the frame buffer to the external controller.
-Gary
/***********************************************************************************************************************
* Copyright [2015] Renesas Electronics Corporation and/or its licensors. All Rights Reserved.
*
* The contents of this file (the �contents�) are proprietary and confidential to Renesas Electronics Corporation
* and/or its licensors (�Renesas�) and subject to statutory and contractual protections.
*
* Unless otherwise expressly agreed in writing between Renesas and you: 1) you may not use, copy, modify, distribute,
* display, or perform the contents; 2) you may not use any name or mark of Renesas for advertising or publicity
* purposes or in connection with your use of the contents; 3) RENESAS MAKES NO WARRANTY OR REPRESENTATIONS ABOUT THE
* SUITABILITY OF THE CONTENTS FOR ANY PURPOSE; THE CONTENTS ARE PROVIDED �AS IS� WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
* NON-INFRINGEMENT; AND 4) RENESAS SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, OR CONSEQUENTIAL DAMAGES,
* INCLUDING DAMAGES RESULTING FROM LOSS OF USE, DATA, OR PROJECTS, WHETHER IN AN ACTION OF CONTRACT OR TORT, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE CONTENTS. Third-party contents included in this file may
* be subject to different terms.
**********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : synergy_grapics_driver_565rgb.c
* Description : Graphics LCD driver - AS-IS integration with GUIX
**********************************************************************************************************************/
/**********************************************************************************************************************
* History : DD.MM.YYYY Version Description
* 04.02.2015 1.00 Initial Release.
**********************************************************************************************************************/
/***********************************************************************************************************************
* Includes <System Includes> , "Project Includes"
**********************************************************************************************************************/
#include <stdio.h>
#include <string.h>
#include "gx_api.h"
#include "r_dmac.h"
#include "r_icu.h"
#include "r_transfer_api.h"
#include "r_external_irq_api.h"
#include "hal_data.h"
/***********************************************************************************************************************
* Macro definitions
**********************************************************************************************************************/
#define DISPLAY_XRES 240
#define DISPLAY_YRES 320
#define FRAME_BUFFER_SIZE (DISPLAY_XRES * DISPLAY_YRES * 2)
#define LCD_CMD ( *(volatile uint8_t *) 0x80000000)
#ifdef EX_16BIT_BUS
#define LCD_DATA ( *(volatile uint16_t *) 0x80000004)
#else
#define LCD_DATA ( *(volatile uint8_t *) 0x80000004)
#endif
#define LCD_DATAW ( *(volatile uint16_t *) 0x80000004)
#define LCD_RESET IOPORT_PORT_08_PIN_02
#define LCD_MODE8BIT IOPORT_PORT_08_PIN_03
static uint8_t FrameBuffer[FRAME_BUFFER_SIZE];
/***********************************************************************************************************************
* Typedef definitions
**********************************************************************************************************************/
/***********************************************************************************************************************
* Global Variables
**********************************************************************************************************************/
void LCD_Display_On(void);
void LCD_Display_On(void);
void LCD_Display_Off(void);
void LCD_Memory_Fill(uint16_t pixel_color);
void guix_buffer_toggle_565RGB (GX_CANVAS * p_canvas, GX_RECTANGLE * p_dirty);
UINT synergy_graphics_driver_setup (GX_DISPLAY * p_display);
void synergy_graphics_driver_canvas_memory_init (GX_CANVAS * p_canvas);
void ConfigureGUIXDisplayHardware565rgb (GX_DISPLAY * p_display);
/***********************************************************************************************************************
* Private global variables and functions
**********************************************************************************************************************/
/** Frame buffers. each line of frame buffer have to be aligned to 64 bytes boundary. */
/** Graphics LCD driver global variables */
/** indicator for the number of visible frame buffer */
/** Synchronization object between drawing timing by GUIX and display timing by DMA driver */
static TX_SEMAPHORE g_semaphore_dma_done;
/** Graphics DMA callback function */
static void dma_callback(transfer_callback_args_t * p_args);
/** Graphics LCD Controller Initialization **/
static void LCD_Init_ST7789S(void);
/** Graphics LCD, subroutines for register configuration */
static transfer_ctrl_t g_transfer_ctrl;
static transfer_info_t g_transfer_info =
{
.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED,
.repeat_area = TRANSFER_REPEAT_AREA_DESTINATION,
.irq = TRANSFER_IRQ_EACH,
.chain_mode = TRANSFER_CHAIN_MODE_DISABLED,
.src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED,
.size = TRANSFER_SIZE_2_BYTE,
.mode = TRANSFER_MODE_BLOCK,
.p_dest = (void *) 0x80000004,
.p_src = NULL,
.num_blocks = 1,
.length = 1024,
};
static const transfer_cfg_t g_transfer_cfg =
{
.p_info = &g_transfer_info,
.activation_source = ELC_EVENT_ELC_SOFTWARE_EVENT_0,
.auto_enable = false,
.p_callback = dma_callback,
.p_context = &g_transfer_ctrl,
};
const transfer_instance_t g_transfer =
{ .p_ctrl = &g_transfer_ctrl, .p_cfg = &g_transfer_cfg, .p_api = &g_transfer_on_dmac };
/*
external_irq_ctrl_t g_external_irq_ctrl;
const external_irq_cfg_t g_external_irq_cfg =
{
.channel = 4, // IRQ4 Port 1 Pin 11
.trigger = EXTERNAL_IRQ_TRIG_RISING,
.filter_enable = true,
.pclk_div = EXTERNAL_IRQ_PCLK_DIV_BY_1,
.autostart = true,
.p_callback = fmark_callback,
.p_context = &g_external_irq_ctrl,
};
const external_irq_instance_t g_external_irq =
{ .p_ctrl = &g_external_irq_ctrl, .p_cfg = &g_external_irq_cfg, .p_api = &g_external_irq_on_icu };
*/
/** Function prototype from GUIX. TODO: Find a way to remove this dependency. */
VOID _gx_display_driver_565rgb_setup(GX_DISPLAY *display, VOID *aux_data,
VOID (*toggle_function)(struct GX_CANVAS_STRUCT *canvas,
GX_RECTANGLE *dirty_area));
static void dma_callback(transfer_callback_args_t * p_args)
{
SSP_PARAMETER_NOT_USED(p_args);
tx_semaphore_ceiling_put(&g_semaphore_dma_done, 1);
}
/** Graphics Vertical Blanking callback function */
/*
* void fmark_callback(external_irq_callback_args_t * p_args)
{
SSP_PARAMETER_NOT_USED(p_args);
if (g_guix_request_to_inform_available_timing_to_draw)
{
tx_semaphore_ceiling_put(&g_semaphore_fmark, 1);
g_guix_request_to_inform_available_timing_to_draw = false;
}
}
*/
/***********************************************************************************************************************
* @brief GUIX display driver, toggle frame buffer
* @param[in] p_canvas Pointer to GUIX canvas structure
* @param[in] p_dirty Pointer to rectangle area on screen
* @retval none
**********************************************************************************************************************/
void guix_buffer_toggle_565RGB (GX_CANVAS * p_canvas, GX_RECTANGLE * p_dirty)
{
ssp_err_t err;
SSP_PARAMETER_NOT_USED(p_dirty);
LCD_CMD = 0x2C; // Memory Write
/* Sets flag to request LCD driver to inform available timing to start drawing
g_guix_request_to_inform_available_timing_to_draw = true;
tx_semaphore_get(&g_semaphore_fmark, TX_WAIT_FOREVER);
*/
err = g_transfer.p_api->reset(g_transfer.p_ctrl, p_canvas->gx_canvas_memory, NULL, 75); // 320 x 240 x 2 / 1024
if(SSP_SUCCESS != err) __asm("BKPT");
err = g_transfer.p_api->start(g_transfer.p_ctrl, TRANSFER_START_MODE_REPEAT);
if(SSP_SUCCESS != err) __asm("BKPT");
tx_semaphore_get(&g_semaphore_dma_done, TX_WAIT_FOREVER);
LCD_CMD = 0x00; // NOP to end the transfer
}
/***********************************************************************************************************************
* @brief GUIX display driver setup, initialize the graphics LCD panel hardware
* @param[in] p_display Pointer to GUIX display interface structure
* @retval none
**********************************************************************************************************************/
void ConfigureGUIXDisplayHardware565rgb (GX_DISPLAY * p_display)
{
ssp_err_t err;
SSP_PARAMETER_NOT_USED(p_display);
err = tx_semaphore_create(&g_semaphore_dma_done, NULL, 0);
if(SSP_SUCCESS != err) __asm("BKPT");
err = g_transfer.p_api->open(g_transfer.p_ctrl, g_transfer.p_cfg);
if(SSP_SUCCESS != err) __asm("BKPT");
LCD_Init_ST7789S();
LCD_Memory_Fill(0x1F);
LCD_Display_On();
}
/***********************************************************************************************************************
* @brief GUIX display driver setup, set the graphics LCD driver input color format as RGB565
* @param[in] p_display Pointer to GUIX display interface structure
* @retval none
**********************************************************************************************************************/
UINT synergy_graphics_driver_setup (GX_DISPLAY * p_display)
{
_gx_display_driver_565rgb_setup(p_display, GX_NULL, guix_buffer_toggle_565RGB);
p_display->gx_display_handle = 0;
ConfigureGUIXDisplayHardware565rgb(p_display);
return GX_SUCCESS;
}
/***********************************************************************************************************************
* @brief GUIX display driver setup, set the frame buffer address.
* @param[in] p_canvas Pointer to GUIX canvas structure
* @retval none
**********************************************************************************************************************/
void synergy_graphics_driver_canvas_memory_init (GX_CANVAS * p_canvas)
{
p_canvas->gx_canvas_memory = (GX_COLOR *) FrameBuffer;
}
void LCD_Display_On(void)
{
LCD_CMD = 0x29; //
}
void LCD_Display_Off(void)
{
LCD_CMD = 0x28; //
}
void LCD_Memory_Fill(uint16_t pixel_color)
{
uint32_t i;
LCD_CMD = 0x2C; // Memory Write
for(i=0; i<(240*320); i++)
{
LCD_DATAW = pixel_color;
}
LCD_CMD = 0x00; // NOP to end the transfer
}
static void LCD_Init_ST7789S(void)
{
uint8_t data, id1,id2,id3, dummy;
g_ioport.p_api->pinWrite(LCD_RESET, IOPORT_LEVEL_HIGH);
g_ioport.p_api->pinWrite(LCD_RESET, IOPORT_LEVEL_LOW);
#ifdef EX_16BIT_BUS
g_ioport.p_api->pinWrite(LCD_MODE8BIT, IOPORT_LEVEL_LOW); // Set 16 bit I/F
#else
g_ioport.p_api->pinWrite(LCD_MODE8BIT, IOPORT_LEVEL_HIGH); // Set 8 bit I/F
#endif
R_BSP_SoftwareDelay(100,BSP_DELAY_UNITS_MILLISECONDS);
g_ioport.p_api->pinWrite(LCD_RESET, IOPORT_LEVEL_HIGH);
R_BSP_SoftwareDelay(120,BSP_DELAY_UNITS_MILLISECONDS);
LCD_CMD = 0x11; // Exit Sleep
R_BSP_SoftwareDelay(10,BSP_DELAY_UNITS_MILLISECONDS);
LCD_CMD = 0x36; // Memory Data Access Control
LCD_DATA = 0x00; // Row address order RGB color mode
LCD_CMD = 0x3A; // Interface Pixel Format
LCD_DATA = 0x55; // 16 bit per pixel, 65k RGB
LCD_CMD = 0xB2; // Porch Setting
LCD_DATA = 0x0C;
LCD_DATA = 0x0C;
LCD_DATA = 0x00;
LCD_DATA = 0x33;
LCD_DATA = 0x33;
LCD_CMD = 0xB7; // Gate Control
LCD_DATA = 0x35;
LCD_CMD = 0xBB; // VCOM Setting
LCD_DATA = 0x2B;
LCD_CMD = 0xC0; // LCM Control
LCD_DATA = 0x2C;
LCD_CMD = 0xC2; // VDV and VRH Command Enable
LCD_DATA = 0x01;
LCD_DATA = 0xFF;
LCD_CMD = 0xC3; // VRH Set
LCD_DATA = 0x11;
LCD_CMD = 0xC4; // VDV Set
LCD_DATA = 0x20;
LCD_CMD = 0xC6; // Frame Rate Control
LCD_DATA = 0x0F;
LCD_CMD = 0xD0; // Power Control 1
LCD_DATA = 0xA4;
LCD_DATA = 0xA1;
LCD_CMD = 0xE0; // Positive Voltage Gamma control
LCD_DATA = 0xD0;
LCD_DATA = 0x00;
LCD_DATA = 0x05;
LCD_DATA = 0x0E;
LCD_DATA = 0x15;
LCD_DATA = 0x0D;
LCD_DATA = 0x37;
LCD_DATA = 0x43;
LCD_DATA = 0x47;
LCD_DATA = 0x09;
LCD_DATA = 0x15;
LCD_DATA = 0x12;
LCD_DATA = 0x16;
LCD_DATA = 0x19;
LCD_CMD = 0xE1; // Negative Voltage Gamma control
LCD_DATA = 0xD0;
LCD_DATA = 0x00;
LCD_DATA = 0x05;
LCD_DATA = 0x0D;
LCD_DATA = 0x0C;
LCD_DATA = 0x06;
LCD_DATA = 0x2D;
LCD_DATA = 0x44;
LCD_DATA = 0x40;
LCD_DATA = 0x0E;
LCD_DATA = 0x1C;
LCD_DATA = 0x18;
LCD_DATA = 0x16;
LCD_DATA = 0x19;
LCD_CMD = 0x2A; // X Address Set
LCD_DATA = 0x00; // 0-239
LCD_DATA = 0x00; //
LCD_DATA = 0x00; //
LCD_DATA = 0xEF; //
LCD_CMD = 0x2B; // Y Address Set
LCD_DATA = 0x00; // 0-319
LCD_DATA = 0x00; //
LCD_DATA = 0x01; //
LCD_DATA = 0x3F; //
}