This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/TM4C1294NCPDT: CCS 7.2.0

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: EK-TM4C123GXL

Tool/software: TI C/C++ Compiler

Hi Guys,

I have an issue regarding interfacing of the LCD graphics from Kentec part number- Kentec480x272x16_SSD1963

I have running code which is correct to display the LCD in Landscape mode.

Now i need to flip the display mode to Portrait mode.

While making the #define Portrait it doesn't work as stated in the .c file "Kentec480x272x16_SSD1963_8bit.c"

Please let me how can i achieve this.

Please once check the attached files and guide me how to get it done and what could be the components ghat need to be change to make it done.

Host Processor- TI TIVA C SERIES TM4C1294CNPDT

CCS Version- 7.2

Tiva C Series Library- TivaWare_C_Series-2.1.4.178

ARM Compiler- TI v17.6.0STS

Regards

Saurabh

Files-

Kentec480x272x16_SSD1963_8bit.c

//*****************************************************************************
//
// Kentec480x272x16_SSD1963_8bit.c - Display driver for the Kentec
// K430WQC-V3-F TFT display with an SSD1963
// controller. This version assumes an
// 8080-8bit interface between the micro
// and display.
//
//*****************************************************************************

//*****************************************************************************
//
//! \addtogroup display_api
//! @{
//
//*****************************************************************************
#include "stdint.h"
#include "stdbool.h"

#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
//#include "driverlib/epi.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/rom.h"
#include "grlib/grlib.h"
#include "Kentec480x272x16_SSD1963_8bit.h"
//#include "drivers/set_pinout.h"

//*****************************************************************************
//
// This driver operates in four different screen orientations. They are:
//
// * Portrait - The screen is taller than it is wide, and the flex connector is
// on the left of the display. This is selected by defining
// PORTRAIT.
//
// * Landscape - The screen is wider than it is tall, and the flex connector is
// on the bottom of the display. This is selected by defining
// LANDSCAPE.
//
// * Portrait flip - The screen is taller than it is wide, and the flex
// connector is on the right of the display. This is
// selected by defining PORTRAIT_FLIP.
//
// * Landscape flip - The screen is wider than it is tall, and the flex
// connector is on the top of the display. This is
// selected by defining LANDSCAPE_FLIP.
//
// These can also be imagined in terms of screen rotation; if portrait mode is
// 0 degrees of screen rotation, landscape is 90 degrees of counter-clockwise
// rotation, portrait flip is 180 degrees of rotation, and landscape flip is
// 270 degress of counter-clockwise rotation.
//
// If no screen orientation is selected, "landscape flip" mode will be used.
//
//*****************************************************************************
#if ! defined(PORTRAIT) && ! defined(PORTRAIT_FLIP) && \
! defined(LANDSCAPE) && ! defined(LANDSCAPE_FLIP)
//#define LANDSCAPE
#define PORTRAIT
#endif

#define LCD_HEIGHT 272
#define LCD_WIDTH 480
//*****************************************************************************
//
// Various definitions controlling coordinate space mapping and drawing
// direction in the four supported orientations.
//
//*****************************************************************************
#ifdef PORTRAIT
#define HORIZ_DIRECTION 0xa0 //160
#define VERT_DIRECTION 0x80 //128
#define MAPPED_X(x, y) (LCD_WIDTH-1- (y))
#define MAPPED_Y(x, y) (x)
#endif
#ifdef LANDSCAPE
#define HORIZ_DIRECTION 0x00 //0
#define VERT_DIRECTION 0x20 //32
#define MAPPED_X(x, y) (x)
#define MAPPED_Y(x, y) (y)

#endif
#ifdef PORTRAIT_FLIP
#define HORIZ_DIRECTION 0xa2
#define VERT_DIRECTION 0x81
#define MAPPED_X(x, y) (y)
#define MAPPED_Y(x, y) (LCD_HEIGHT-1 - (x))
#endif
#ifdef LANDSCAPE_FLIP
#define HORIZ_DIRECTION 0x02
#define VERT_DIRECTION 0x01
#define MAPPED_X(x, y) (LCD_WIDTH- (x))
#define MAPPED_Y(x, y) (LCD_HEIGHT- (y))
#endif

//*****************************************************************************
//
// Defines for the pins that are used to communicate with the SSD1963.
//
//*****************************************************************************

#define LCD_DATAH_PERIPH SYSCTL_PERIPH_GPIOD
#define LCD_DATAH_BASE GPIO_PORTD_BASE
#define LCD_DATAH_PINS 0xFF

//
// LCD control line GPIO definitions.
//
#define LCD_CS_PERIPH SYSCTL_PERIPH_GPIOL
#define LCD_CS_BASE GPIO_PORTL_BASE
#define LCD_CS_PIN GPIO_PIN_3
#define LCD_RST_PERIPH SYSCTL_PERIPH_GPIOL
#define LCD_RST_BASE GPIO_PORTL_BASE
#define LCD_RST_PIN GPIO_PIN_4
#define LCD_DC_PERIPH SYSCTL_PERIPH_GPIOL
#define LCD_DC_BASE GPIO_PORTL_BASE
#define LCD_DC_PIN GPIO_PIN_2
#define LCD_RD_PERIPH SYSCTL_PERIPH_GPIOL
#define LCD_RD_BASE GPIO_PORTL_BASE
#define LCD_RD_PIN GPIO_PIN_1
#define LCD_WR_PERIPH SYSCTL_PERIPH_GPIOL
#define LCD_WR_BASE GPIO_PORTL_BASE
#define LCD_WR_PIN GPIO_PIN_0

//*****************************************************************************
//
// Backlight control GPIO used with the Flash/SRAM/LCD daughter board.
//
//*****************************************************************************
#define LCD_BACKLIGHT_PERIPH SYSCTL_PERIPH_GPIOG
#define LCD_BACKLIGHT_BASE GPIO_PORTG_BASE
#define LCD_BACKLIGHT_PIN GPIO_PIN_1

//*****************************************************************************
//
// Macro used to set the LCD data bus in preparation for writing a byte to the
// device.
//
//*****************************************************************************
#define SET_LCD_DATA(ucByte) \
{ \
HWREG(LCD_DATAH_BASE + GPIO_O_DATA + (LCD_DATAH_PINS << 2)) = (ucByte); \
}

//*****************************************************************************
//
// Various internal SSD1963 registers name labels
//
//*****************************************************************************
#define ENTRY_MODE_DEFAULT 0x6830
#define MAKE_ENTRY_MODE(x) ((ENTRY_MODE_DEFAULT & 0xFF00) | (x))

//*****************************************************************************
//
// The dimensions of the LCD panel.
//
//*****************************************************************************
#define LCD_VERTICAL_MAX 272
#define LCD_HORIZONTAL_MAX 480

//*****************************************************************************
//
// Translates a 24-bit RGB color to a display driver-specific color.
//
// \param c is the 24-bit RGB color. The least-significant byte is the blue
// channel, the next byte is the green channel, and the third byte is the red
// channel.
//
// This macro translates a 24-bit RGB color into a value that can be written
// into the display's frame buffer in order to reproduce that color, or the
// closest possible approximation of that color.
//
// \return Returns the display-driver specific color.
//
//*****************************************************************************
#define DPYCOLORTRANSLATE(c) ((((c) & 0x00f80000) >> 8) | \
(((c) & 0x0000fc00) >> 5) | \
(((c) & 0x000000f8) >> 3))

//*****************************************************************************
//
// Function pointer types for low level LCD controller access functions.
//
//*****************************************************************************
typedef void (*pfnWriteData)(unsigned short usData);
typedef void (*pfnWriteSetting)(unsigned short usData);
typedef void (*pfnWriteCommand)(unsigned short ucData);

//*****************************************************************************
//
// Function pointers for low level LCD controller access functions.
//
//*****************************************************************************

static void WriteDataGPIO(unsigned short usData);
static void WriteSettingGPIO(unsigned short usData);
static void WriteCommandGPIO(unsigned short ucData);

pfnWriteData WriteData = WriteDataGPIO;
pfnWriteData WriteSetting = WriteSettingGPIO;
pfnWriteCommand WriteCommand = WriteCommandGPIO;

//LCD Back Light On
void LCD_BackLight_ON(void)
{
HWREG(LCD_BACKLIGHT_BASE + GPIO_O_DATA + (LCD_BACKLIGHT_PIN << 2)) = LCD_BACKLIGHT_PIN;//0;
}

//LCD Back Light Off
void LCD_BackLight_OFF(void)
{
HWREG(LCD_BACKLIGHT_BASE + GPIO_O_DATA + (LCD_BACKLIGHT_PIN << 2)) = 0;//LCD_BACKLIGHT_PIN;
}
//*****************************************************************************
//
// Writes a data word to the SSD1963. This function implements the basic GPIO
// interface to the LCD display.
//
//*****************************************************************************
static void
WriteDataGPIO(unsigned short usData)
{
// HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = 0;

//
// Write the most significant byte of the data to the bus.
//
SET_LCD_DATA((usData >> 11)<<3);

//
// Assert the write enable signal. We need to do this 2 times to ensure
// that we don't violate the timing requirements for the display.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;

//
// Deassert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;

//
// Write the mid byte of the data to the bus.
//
SET_LCD_DATA((usData >> 5)<<2);

//
// Assert the write enable signal. We need to do this 2 times to ensure
// that we don't violate the timing requirements for the display.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;

//
// Deassert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;

//
// Write the least significant byte of the data to the bus.
//
SET_LCD_DATA(usData<<3);

//
// Assert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;

//
// Deassert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
}
static void
WriteSettingGPIO(unsigned short usData)
{
//
// Write the least significant byte of the data to the bus.
//
SET_LCD_DATA(usData);
//
// Assert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;

//
// Deassert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
}


//*****************************************************************************
//
// Writes a command to the SSD1963. This function implements the basic GPIO
// interface to the LCD display.
//
//*****************************************************************************
static void
WriteCommandGPIO(unsigned short ucData)
{
//
// Write the most significant byte of the data to the bus. This is always
// 0 since commands are no more than 8 bits.
//
SET_LCD_DATA(0);

//
// Assert DC
//
HWREG(LCD_DC_BASE + GPIO_O_DATA + (LCD_DC_PIN << 2)) = 0;

//
// Assert the write enable signal. We need to do this 2 times to ensure
// that we don't violate the timing requirements for the display.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;

//
// Deassert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;

//
// Write the least significant byte of the data to the bus.
//
SET_LCD_DATA(ucData);

//
// Assert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = 0;

//
// Deassert the write enable signal.
//
HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;
// HWREG(LCD_WR_BASE + GPIO_O_DATA + (LCD_WR_PIN << 2)) = LCD_WR_PIN;

//
// Set the DC signal high, indicating that following writes are data.
//
HWREG(LCD_DC_BASE + GPIO_O_DATA + (LCD_DC_PIN << 2)) = LCD_DC_PIN;
// HWREG(LCD_DC_BASE + GPIO_O_DATA + (LCD_DC_PIN << 2)) = LCD_DC_PIN;
// HWREG(LCD_DC_BASE + GPIO_O_DATA + (LCD_DC_PIN << 2)) = LCD_DC_PIN;
}
//*****************************************************************************
//
// Initializes the pins required for the GPIO-based LCD interface.
//
// This function configures the GPIO pins used to control the LCD display
// when the basic GPIO interface is in use. On exit, the LCD controller
// has been reset and is ready to receive command and data writes.
//
// \return None.
//
//*****************************************************************************
static void
InitGPIOLCDInterface(unsigned long ulClockMS)
{
/*
//
// Configure the pins that connect to the LCD as GPIO outputs.
//
GPIOPinTypeGPIOOutput(LCD_DATAH_BASE, LCD_DATAH_PINS);
GPIOPinTypeGPIOOutput(LCD_DC_BASE, LCD_DC_PIN);
GPIOPinTypeGPIOOutput(LCD_RD_BASE, LCD_RD_PIN);
GPIOPinTypeGPIOOutput(LCD_WR_BASE, LCD_WR_PIN);
GPIOPinTypeGPIOOutput(LCD_CS_BASE, LCD_CS_PIN);
GPIOPinTypeGPIOOutput(LCD_RST_BASE, LCD_RST_PIN);
*/
//
// Configure the pins that connect to the LCD as GPIO outputs.
//

HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0xff;
GPIODirModeSet(LCD_DATAH_BASE, LCD_DATAH_PINS, GPIO_DIR_MODE_OUT);
GPIOPadConfigSet(LCD_DATAH_BASE, LCD_DATAH_PINS, GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD);
GPIODirModeSet(LCD_DC_BASE, LCD_DC_PIN, GPIO_DIR_MODE_OUT);
GPIOPadConfigSet(LCD_DC_BASE, LCD_DC_PIN, GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD);
GPIODirModeSet(LCD_RD_BASE, LCD_RD_PIN, GPIO_DIR_MODE_OUT);
GPIOPadConfigSet(LCD_RD_BASE, LCD_RD_PIN, GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD);
GPIODirModeSet(LCD_WR_BASE, LCD_WR_PIN, GPIO_DIR_MODE_OUT);
GPIOPadConfigSet(LCD_WR_BASE, LCD_WR_PIN, GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD);
GPIODirModeSet(LCD_CS_BASE, LCD_CS_PIN, GPIO_DIR_MODE_OUT);
GPIOPadConfigSet(LCD_CS_BASE, LCD_CS_PIN, GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD);
GPIODirModeSet(LCD_RST_BASE, LCD_RST_PIN, GPIO_DIR_MODE_OUT);
GPIOPadConfigSet(LCD_RST_BASE, LCD_RST_PIN, GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD);
GPIOPinTypeGPIOOutput(LCD_BACKLIGHT_BASE, LCD_BACKLIGHT_PIN);
//
// Set the LCD control pins to their default values. This also asserts the
// LCD reset signal.
//
GPIOPinWrite(LCD_CS_BASE, LCD_CS_PIN, LCD_CS_PIN);
GPIOPinWrite(LCD_DATAH_BASE, LCD_DATAH_PINS, 0x00);
GPIOPinWrite(LCD_DC_BASE, LCD_DC_PIN, 0x00);
GPIOPinWrite(LCD_RD_BASE, LCD_RD_PIN, LCD_RD_PIN);
GPIOPinWrite(LCD_WR_BASE, LCD_WR_PIN, LCD_WR_PIN);
GPIOPinWrite(LCD_RST_BASE, LCD_RST_PIN, 0x00);
GPIOPinWrite(LCD_CS_BASE, LCD_CS_PIN, 0);
LCD_BackLight_ON();

//
// Delay for 1ms.
//
SysCtlDelay(26666);

//
// Deassert the LCD reset signal.
//
GPIOPinWrite(LCD_RST_BASE, LCD_RST_PIN, LCD_RST_PIN);

//
// Delay for 1ms while the LCD comes out of reset.
//
SysCtlDelay(26666);
}


//*****************************************************************************
//
//! Initializes the display driver.
//!
//! This function initializes the SSD1963 display controller on the panel,
//! preparing it to display data.
//!
//! \return None.
//
//*****************************************************************************
void
Kentec480x272x16_SSD1963Init(void)
{
unsigned long ulCount;

//
// Get the current processor clock frequency.
//
//SysCtlClockGet() / (3 * 1000);


// Enable the GPIO peripherals used to interface to the SSD1963.
//
SysCtlPeripheralEnable(LCD_DATAH_PERIPH);
SysCtlPeripheralEnable(LCD_DC_PERIPH);
SysCtlPeripheralEnable(LCD_RD_PERIPH);
SysCtlPeripheralEnable(LCD_WR_PERIPH);
SysCtlPeripheralEnable(LCD_RST_PERIPH);
SysCtlPeripheralEnable(LCD_CS_PERIPH);
SysCtlPeripheralEnable(LCD_BACKLIGHT_PERIPH);

//
// Perform low level interface initialization depending upon how the LCD
// is connected to the Stellaris microcontroller. This varies depending
// upon the daughter board connected it is possible that a daughter board
// can drive the LCD directly rather than via the basic GPIO interface.
//
{
//
// Initialize the GPIOs used to interface to the LCD controller.
//
InitGPIOLCDInterface(26666);
}

WriteCommand(0x0001); // software reset
//
// Delay for 1ms.
//
SysCtlDelay(26666);

WriteCommand(0x00E2); //PLL multiplier, set PLL clock to 120M
WriteSetting(0x0014); //29
WriteSetting(0x0003);
WriteSetting(0x0004);

WriteCommand(0x00E0); // PLL enable
WriteSetting(0x0001);
//
// Delay for 1/10ms.
//
SysCtlDelay(26666/10);

WriteCommand(0x00E0);
WriteSetting(0x0003);
//
// Delay for 1/5ms.
//
SysCtlDelay(26666/5);


WriteCommand(0x00E6); //PLL setting for PCLK, depends on resolution
WriteSetting(0x0003); //04
WriteSetting(0x00A0); //B9
WriteSetting(0x0000); //38

WriteCommand(0x00B0); //LCD SPECIFICATION
WriteSetting(0x0020); //24
WriteSetting(0x0000);
WriteSetting(0x01); //Set HDP
WriteSetting(0xDF);
WriteSetting(0x01);
WriteSetting(0x0F);
WriteSetting(0x00);

WriteCommand(0x00B4); //HSYNC
WriteSetting(0x02);
WriteSetting(0x0D);
WriteSetting(0x00);
WriteSetting(0x25);
WriteSetting(0x02);
WriteSetting(0x00);
WriteSetting(0x00);
WriteSetting(0x00);

WriteCommand(0x00B6); //VSYNC
WriteSetting(0x01);
WriteSetting(0x1E);
WriteSetting(0x00);
WriteSetting(0x08);
WriteSetting(0x01);
WriteSetting(0x00);
WriteSetting(0x00);

WriteCommand(0xB8);
WriteSetting(0x0007); //GPIO3=input, GPIO[2:0]=output
WriteSetting(0x0001); //GPIO0 normal

WriteCommand(0xBA);
WriteSetting(0x000D); //GPIO[3:0] out 1 //GPIO[1]=0, RESET G2452

WriteCommand(0x36); //rotation
//WriteSetting(0x0000);
WriteSetting(0x0020); //@Saurabh_for vertical mode display

WriteCommand(0x00F0); //pixel data interface
// WriteSetting(0x0003);
WriteSetting(0x0000);

//
// Delay for 1ms.
//
SysCtlDelay(26666/2);

//LCD_clear();

WriteCommand(0x00BE); //set PWM for B/L
WriteSetting(0x0001); //06 frequency
WriteSetting(0x00FF); //C0 duty
WriteSetting(0x0009); //bit[3]DBC enable,bit[0]PWM enable
WriteSetting(0x00FF); //C0 DBC manual brightness
WriteSetting(0x0088); //10 DBC minimum brightness
WriteSetting(0x0000); //08 Brightness prescaler

WriteCommand(0x00d4);
WriteSetting(0x0000);
WriteSetting(0x001C);
WriteSetting(0x0020);
WriteSetting(0x0000);
WriteSetting(0x0046);
WriteSetting(0x0050);
WriteSetting(0x0000);
WriteSetting(0x00A8);
WriteSetting(0x00C0);

WriteCommand(0x00d0); //Set DBC Configuration
//WriteSetting(0x000D); //DBC Aggressive mode
//WriteSetting(0x0001); //DBC disable
WriteSetting(0x0029); //@Saurabh

//WriteCommand(0x0021); //Enter Invert Mode

WriteCommand(0x0029); //display on

//
// Clear the contents of the display buffer.
//
WriteCommand(0x002A);
WriteSetting(0);
WriteSetting(0);
WriteSetting((LCD_WIDTH-1)>>8);
WriteSetting((LCD_WIDTH-1)&0x00ff);
WriteCommand(0x002b);
WriteSetting(0);
WriteSetting(0);
WriteSetting((LCD_HEIGHT-1)>>8);
WriteSetting((LCD_HEIGHT-1)&0x00ff);
WriteCommand(0x002c);
for(ulCount = 0; ulCount < (LCD_WIDTH * LCD_HEIGHT); ulCount++)
{
WriteData(0x0000);
}
}
//*****************************************************************************
//
//! Draws a pixel on the screen.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX is the X coordinate of the pixel.
//! \param lY is the Y coordinate of the pixel.
//! \param ulValue is the color of the pixel.
//!
//! This function sets the given pixel to a particular color. The coordinates
//! of the pixel are assumed to be within the extents of the display.
//!
//! \return None.
//
//*****************************************************************************
static void
Kentec480x272x16_SSD1963PixelDraw(void *pvDisplayData, int32_t lX, int32_t lY,
uint32_t ulValue)
{
//
// Set the X address of the display cursor.
//
WriteCommand(0x2A);
WriteSetting(MAPPED_X(lX, lY)>>8);
WriteSetting(MAPPED_X(lX, lY)&0xff);
WriteSetting((LCD_WIDTH-1)>>8);
WriteSetting((LCD_WIDTH-1)&0xff);

//
// Set the Y address of the display cursor.
//
WriteCommand(0x2B);
WriteSetting(MAPPED_Y(lX, lY)>>8);
WriteSetting(MAPPED_Y(lX, lY)&0xff);
WriteSetting((LCD_HEIGHT-1)>>8);
WriteSetting((LCD_HEIGHT-1)&0xff);

//
// Write the pixel value.
//
WriteCommand(0x2C);
WriteData(ulValue);
}

void
Kentec480x272x16_SSD1963PixelDraw_x(long lX, long lY,
unsigned long ulValue)
{
//
// Set the X address of the display cursor.
//
WriteCommand(0x2A);
WriteSetting(MAPPED_X(lX, lY)>>8);
WriteSetting(MAPPED_X(lX, lY)&0xff);
WriteSetting((LCD_WIDTH-1)>>8);
WriteSetting((LCD_WIDTH-1)&0xff);

//
// Set the Y address of the display cursor.
//
WriteCommand(0x2B);
WriteSetting(MAPPED_Y(lX, lY)>>8);
WriteSetting(MAPPED_Y(lX, lY)&0xff);
WriteSetting((LCD_HEIGHT-1)>>8);
WriteSetting((LCD_HEIGHT-1)&0xff);

//
// Write the pixel value.
//
WriteCommand(0x2C);
WriteData(ulValue);
}


//*****************************************************************************
//
//! Draws a horizontal sequence of pixels on the screen.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX is the X coordinate of the first pixel.
//! \param lY is the Y coordinate of the first pixel.
//! \param lX0 is sub-pixel offset within the pixel data, which is valid for 1
//! or 4 bit per pixel formats.
//! \param lCount is the number of pixels to draw.
//! \param lBPP is the number of bits per pixel; must be 1, 4, or 8.
//! \param pucData is a pointer to the pixel data. For 1 and 4 bit per pixel
//! formats, the most significant bit(s) represent the left-most pixel.
//! \param pucPalette is a pointer to the palette used to draw the pixels.
//!
//! This function draws a horizontal sequence of pixels on the screen, using
//! the supplied palette. For 1 bit per pixel format, the palette contains
//! pre-translated colors; for 4 and 8 bit per pixel formats, the palette
//! contains 24-bit RGB values that must be translated before being written to
//! the display.
//!
//! \return None.
//
//*****************************************************************************
static void
Kentec480x272x16_SSD1963PixelDrawMultiple(void *pvDisplayData, int32_t lX,
int32_t lY, int32_t lX0, int32_t lCount,
int32_t lBPP,
const uint8_t *pucData,
const uint8_t *pucPalette)
{
uint32_t ulByte;

//
// Set the cursor increment to left to right, followed by top to bottom.
//
WriteCommand(0x36);
WriteSetting(MAKE_ENTRY_MODE(HORIZ_DIRECTION));

//
// Set the X address of the display cursor.
//
WriteCommand(0x2A);
WriteSetting(MAPPED_X(lX, lY)>>8);
WriteSetting(MAPPED_X(lX, lY)&0xff);
WriteSetting((LCD_WIDTH-1)>>8);
WriteSetting((LCD_WIDTH-1)&0xff);

//
// Set the Y address of the display cursor.
//
WriteCommand(0x2B);
WriteSetting(MAPPED_Y(lX, lY)>>8);
WriteSetting(MAPPED_Y(lX, lY)&0xff);
WriteSetting((LCD_HEIGHT-1)>>8);
WriteSetting((LCD_HEIGHT-1)&0xff);


//
// Write the data RAM write command.
//
WriteCommand(0x2C);

//
// Determine how to interpret the pixel data based on the number of bits
// per pixel.
//
switch(lBPP)
{
//
// The pixel data is in 1 bit per pixel format.
//
case 1:
{
//
// Loop while there are more pixels to draw.
//
while(lCount)
{
//
// Get the next byte of image data.
//
ulByte = *pucData++;

//
// Loop through the pixels in this byte of image data.
//
for(; (lX0 < 8) && lCount; lX0++, lCount--)
{
//
// Draw this pixel in the appropriate color.
//
WriteData(((unsigned long *)pucPalette)[(ulByte >>
(7 - lX0)) & 1]);
}

//
// Start at the beginning of the next byte of image data.
//
lX0 = 0;
}

//
// The image data has been drawn.
//
break;
}

//
// The pixel data is in 4 bit per pixel format.
//
case 4:
{
//
// Loop while there are more pixels to draw. "Duff's device" is
// used to jump into the middle of the loop if the first nibble of
// the pixel data should not be used. Duff's device makes use of
// the fact that a case statement is legal anywhere within a
// sub-block of a switch statement. See
// en.wikipedia.org/.../Duff's_device for detailed
// information about Duff's device.
//
switch(lX0 & 1)
{
case 0:
while(lCount)
{
//
// Get the upper nibble of the next byte of pixel data
// and extract the corresponding entry from the
// palette.
//
ulByte = (*pucData >> 4) * 3;
ulByte = (*(unsigned long *)(pucPalette + ulByte) &
0x00ffffff);

//
// Translate this palette entry and write it to the
// screen.
//
WriteData(DPYCOLORTRANSLATE(ulByte));

//
// Decrement the count of pixels to draw.
//
lCount--;

//
// See if there is another pixel to draw.
//
if(lCount)
{
case 1:
//
// Get the lower nibble of the next byte of pixel
// data and extract the corresponding entry from
// the palette.
//
ulByte = (*pucData++ & 15) * 3;
ulByte = (*(unsigned long *)(pucPalette + ulByte) &
0x00ffffff);

//
// Translate this palette entry and write it to the
// screen.
//
WriteData(DPYCOLORTRANSLATE(ulByte));

//
// Decrement the count of pixels to draw.
//
lCount--;
}
}
}

//
// The image data has been drawn.
//
break;
}

//
// The pixel data is in 8 bit per pixel format.
//
case 8:
{
//
// Loop while there are more pixels to draw.
//
while(lCount--)
{
//
// Get the next byte of pixel data and extract the
// corresponding entry from the palette.
//
ulByte = *pucData++ * 3;
ulByte = *(unsigned long *)(pucPalette + ulByte) & 0x00ffffff;

//
// Translate this palette entry and write it to the screen.
//
WriteData(DPYCOLORTRANSLATE(ulByte));
}

//
// The image data has been drawn.
//
break;
}
}

// UARTprintf("\n\Draw Multi Pixel finish \n");
}

//*****************************************************************************
//
//! Draws a horizontal line.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX1 is the X coordinate of the start of the line.
//! \param lX2 is the X coordinate of the end of the line.
//! \param lY is the Y coordinate of the line.
//! \param ulValue is the color of the line.
//!
//! This function draws a horizontal line on the display. The coordinates of
//! the line are assumed to be within the extents of the display.
//!
//! \return None.
//
//*****************************************************************************
static void
Kentec480x272x16_SSD1963LineDrawH(void *pvDisplayData, int32_t lX1, int32_t lX2,
int32_t lY, uint32_t ulValue)
{
//
// Set the cursor increment to left to right, followed by top to bottom.
//
WriteCommand(0x36);
WriteSetting(MAKE_ENTRY_MODE(HORIZ_DIRECTION));

//
// Set the X address of the display cursor.
//
WriteCommand(0x2A);
WriteSetting(MAPPED_X(lX1, lY)>>8);
WriteSetting(MAPPED_X(lX1, lY)&0xff);
WriteSetting((LCD_WIDTH-1)>>8);
WriteSetting((LCD_WIDTH-1)&0xff);

//
// Set the Y address of the display cursor.
//
WriteCommand(0x2B);
WriteSetting(MAPPED_Y(lX1, lY)>>8);
WriteSetting(MAPPED_Y(lX1, lY)&0xff);
WriteSetting((LCD_HEIGHT-1)>>8);
WriteSetting((LCD_HEIGHT-1)&0xff);


//
// Write the data RAM write command.
//
WriteCommand(0x2C);

//
// Loop through the pixels of this horizontal line.
//
while(lX1++ <= lX2)
{
//
// Write the pixel value.
//
WriteData(ulValue);
}
//UARTprintf("\n\Draw Horiz finish %d \n",MAKE_ENTRY_MODE(HORIZ_DIRECTION));
}

//*****************************************************************************
//
//! Draws a vertical line.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX is the X coordinate of the line.
//! \param lY1 is the Y coordinate of the start of the line.
//! \param lY2 is the Y coordinate of the end of the line.
//! \param ulValue is the color of the line.
//!
//! This function draws a vertical line on the display. The coordinates of the
//! line are assumed to be within the extents of the display.
//!
//! \return None.
//
//*****************************************************************************
static void
Kentec480x272x16_SSD1963LineDrawV(void *pvDisplayData, int32_t lX, int32_t lY1,
int32_t lY2, uint32_t ulValue)
{
//
// Set the cursor increment to top to bottom, followed by left to right.
//
WriteCommand(0x36);
WriteSetting(MAKE_ENTRY_MODE(VERT_DIRECTION));

//
// Set the X address of the display cursor.
//
WriteCommand(0x2A);
WriteSetting(MAPPED_X(lX, lY1)>>8);
WriteSetting(MAPPED_X(lX, lY1)&0xff);
WriteSetting((LCD_WIDTH-1)>>8);
WriteSetting((LCD_WIDTH-1)&0xff);

//
// Set the Y address of the display cursor.
//
WriteCommand(0x2B);
WriteSetting(MAPPED_Y(lX, lY1)>>8);
WriteSetting(MAPPED_Y(lX, lY1)&0xff);
WriteSetting((LCD_HEIGHT-1)>>8);
WriteSetting((LCD_HEIGHT-1)&0xff);


//
// Write the data RAM write command.
//
WriteCommand(0x2C);

//
// Loop through the pixels of this vertical line.
//
while(lY1++ <= lY2)
{
//
// Write the pixel value.
//
WriteData(ulValue);
}
//UARTprintf("\n\Draw Vertical over \n");
}

//*****************************************************************************
//
//! Fills a rectangle.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param pRect is a pointer to the structure describing the rectangle.
//! \param ulValue is the color of the rectangle.
//!
//! This function fills a rectangle on the display. The coordinates of the
//! rectangle are assumed to be within the extents of the display, and the
//! rectangle specification is fully inclusive (in other words, both sXMin and
//! sXMax are drawn, along with sYMin and sYMax).
//!
//! \return None.
//
//*****************************************************************************
static void
Kentec480x272x16_SSD1963RectFill(void *pvDisplayData, const tRectangle *pRect,
uint32_t ulValue)
{
long lCount_x, lCount_y;
// unsigned int HDP_S=799;
// unsigned int VDP_S=479;

//
// / Set the cursor increment to top to bottom, followed by left to right.
//
WriteCommand(0x36);
WriteSetting(MAKE_ENTRY_MODE(HORIZ_DIRECTION));


//
// Set the display cursor to the upper left of the rectangle (in application
// coordinate space).
//
WriteCommand(0x2A);
WriteSetting(MAPPED_X(pRect->i16XMin, pRect->i16YMin)>>8);
WriteSetting(MAPPED_X(pRect->i16XMin, pRect->i16YMin)&0xff);
#if (defined PORTRAIT) || (defined LANDSCAPE)
WriteSetting(MAPPED_X(pRect->i16XMax, pRect->i16YMax)>>8);
WriteSetting(MAPPED_X(pRect->i16XMax, pRect->i16YMax)&0xff);

#else
WriteSetting(MAPPED_X(pRect->i16XMin, pRect->i16YMin)>>8);
WriteSetting(MAPPED_X(pRect->i16XMin, pRect->i16YMin)&0xff);

#endif

WriteCommand(0x2B);
WriteSetting(MAPPED_Y(pRect->i16XMin, pRect->i16YMin)>>8);
WriteSetting(MAPPED_Y(pRect->i16XMin, pRect->i16YMin)&0xff);
#if (defined LANDSCAPE_FLIP) || (defined PORTRAIT)
WriteSetting((MAPPED_Y(pRect->i16XMin, pRect->i16YMin) |
(MAPPED_Y(pRect->i16XMax, pRect->i16YMax) << 8))>>8);
WriteSetting((MAPPED_Y(pRect->i16XMin, pRect->i16YMin) |
(MAPPED_Y(pRect->i16XMax, pRect->i16YMax) << 8))&0xff);

#else
WriteSetting((MAPPED_Y(pRect->i16XMax, pRect->i16YMax) |
(MAPPED_Y(pRect->i16XMin, pRect->i16YMin) << 8))>>8);
WriteSetting((MAPPED_Y(pRect->i16XMax, pRect->i16YMax) |
(MAPPED_Y(pRect->i16XMin, pRect->i16YMin) << 8))&0xff);

#endif

//
// Tell the controller we are about to write data into its RAM.
//
WriteCommand(0x2C);

//
// Loop through the pixels of this filled rectangle.
//
// for(lCount = ((pRect->sXMax - pRect->sXMin + 1) *
// (pRect->sYMax - pRect->sYMin + 1)); lCount >= 0; lCount--)
for(lCount_y =(pRect->i16YMax - pRect->i16YMin);lCount_y >= 0; lCount_y--)
{ for(lCount_x =(pRect->i16XMax - pRect->i16XMin);lCount_x >= 0; lCount_x--)
//
// Write the pixel value.
//
WriteData(ulValue);
}
}

//*****************************************************************************
//
//! Translates a 24-bit RGB color to a display driver-specific color.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param ulValue is the 24-bit RGB color. The least-significant byte is the
//! blue channel, the next byte is the green channel, and the third byte is the
//! red channel.
//!
//! This function translates a 24-bit RGB color into a value that can be
//! written into the display's frame buffer in order to reproduce that color,
//! or the closest possible approximation of that color.
//!
//! \return Returns the display-driver specific color.
//
//*****************************************************************************
static uint32_t
Kentec480x272x16_SSD1963ColorTranslate(void *pvDisplayData,
uint32_t ulValue)
{
//
// Translate from a 24-bit RGB color to a 5-6-5 RGB color.
//
return(DPYCOLORTRANSLATE(ulValue));
}

//*****************************************************************************
//
//! Flushes any cached drawing operations.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//!
//! This functions flushes any cached drawing operations to the display. This
//! is useful when a local frame buffer is used for drawing operations, and the
//! flush would copy the local frame buffer to the display. For the SSD1963
//! driver, the flush is a no operation.
//!
//! \return None.
//
//*****************************************************************************
static void
Kentec480x272x16_SSD1963Flush(void *pvDisplayData)
{
//
// There is nothing to be done.
//
}

//*****************************************************************************
//
//! The display structure that describes the driver for the Kentec Display
//! K430WQC-V3-F TFT panel with an SSD1963 controller.
//
//*****************************************************************************
const tDisplay g_sLcd480x272x16_8bit =
{
sizeof(tDisplay),
0,
#if defined(PORTRAIT) || defined(PORTRAIT_FLIP)
LCD_HEIGHT,
LCD_WIDTH,
#else
LCD_WIDTH,
LCD_HEIGHT,
#endif
Kentec480x272x16_SSD1963PixelDraw,
Kentec480x272x16_SSD1963PixelDrawMultiple,
Kentec480x272x16_SSD1963LineDrawH,
Kentec480x272x16_SSD1963LineDrawV,
Kentec480x272x16_SSD1963RectFill,
Kentec480x272x16_SSD1963ColorTranslate,
Kentec480x272x16_SSD1963Flush
};

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

Kentec480x272x16_SSD1963_8bit.h

//*****************************************************************************
//
// Kentec480x272x16_ssd2119_8bit.h - Prototypes for the Kentec K430WQC-V3-F/FF
// display driver with an SSD1963
// controller.
//
//*****************************************************************************

#ifndef __KENTEC480X272X16_SSD1963_8BIT_H__
#define __KENTEC480X272X16_SSD1963_8BIT_H__

//*****************************************************************************
//
// Bit definitions for the LCD control registers in the SRAM/Flash daughter
// board.
//
//*****************************************************************************
#define LCD_CONTROL_NRESET 0x04
#define LCD_CONTROL_YN 0x02
#define LCD_CONTROL_XN 0x01

//
// Read start bit. This is ORed with LCD_COMMAND_PORT or LCD_DATA_PORT to
// initiate a read request from the LCD controller.
//
#define LCD_READ_START 0x00000004

//*****************************************************************************
//
// Prototypes for the globals exported by this driver.
//
//*****************************************************************************
extern void Kentec480x272x16_SSD1963Init(void);
extern const tDisplay g_sLcd480x272x16_8bit;
extern void Kentecx480x272x16_SSD1963SetLCDControl(unsigned char ucMask,
unsigned char ucVal);
extern unsigned long Kentec480x272x16_SSD1963PixelRead(long lX, long lY);
extern void Kentec480x272x16_SSD1963PixelDraw_x(long lX, long lY, unsigned long ulValue);
extern void LCD_BackLight_ON(void);
extern void LCD_BackLight_OFF(void);

#endif // __KENTEC480X272X16_SSD1963_H__

  • Hi,

     I was searching in e2e forums to see if there are relevant posts about Kentec in portrait mode for TM4C, unfortunately I can't find one and neither myself has much experience with the LCD. Probably will not make a difference, I was wondering if the PORTRAIT mode is really defined. Can you comment or just remove all lines in red and try again? 

    #if ! defined(PORTRAIT) && ! defined(PORTRAIT_FLIP) && \
    ! defined(LANDSCAPE) && ! defined(LANDSCAPE_FLIP)
    //#define LANDSCAPE
    #define PORTRAIT
    #endif

  • Hi Charles Tsai,

    Thank you for the response.

    I tried the same but no luck.

    I need to understand the code flow that how the LCD is init with the landscape configuration, any help in this regards is very much appreciated.

    regards

    Saurabh

  • Hello Saurabh,

    From what research I have done, it seems this driver is provided by Kentec themselves and was originally setup for the EK-TM4C123GXL. I reviewed that firmware package vs what you provided for the TM4C1294CNPDT. I don't see much which stands out to me as something that would cause an issue such as what you described.

    Could you try the Kentac display out with an EK-TM4C123GXL and validate that the Portrait mode works as expected with the driver they provided for the EK-TM4C123GXL? As this isn't something we released (to my knowledge, please correct me if wrong) I don't want to assume that the port to the 1294C caused the issue yet.