Hi,
I see that new booster pack Kentec QVGA S1 has been changed from 8-bit parallel interface to SPI interface. So I am attaching the driver for new interface (SPI Interface) and I hope that it will be helpful for others.
Best Regards,
Sattar Malokani
//***************************************************************************** // // Kentec320x240x16_ssd2119_SPI.c - Display driver for the Kentec // BOOSTXL-K350QVG-S1 TFT display with an SSD2119 // controller. This version assumes an SPI 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/ssi.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/timer.h" #include "driverlib/rom.h" #include "driverlib/pin_map.h" #include "grlib/grlib.h" #include "drivers/Kentec320x240x16_SSD2119_SPI.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_FLIP #endif //***************************************************************************** // // Various definitions controlling coordinate space mapping and drawing // direction in the four supported orientations. // //***************************************************************************** #ifdef PORTRAIT #define HORIZ_DIRECTION 0x28 #define VERT_DIRECTION 0x20 #define MAPPED_X(x, y) (319 - (y)) #define MAPPED_Y(x, y) (x) #endif #ifdef LANDSCAPE #define HORIZ_DIRECTION 0x00 #define VERT_DIRECTION 0x08 #define MAPPED_X(x, y) (319 - (x)) #define MAPPED_Y(x, y) (239 - (y)) #endif #ifdef PORTRAIT_FLIP #define HORIZ_DIRECTION 0x18 #define VERT_DIRECTION 0x10 #define MAPPED_X(x, y) (y) #define MAPPED_Y(x, y) (239 - (x)) #endif #ifdef LANDSCAPE_FLIP #define HORIZ_DIRECTION 0x30 #define VERT_DIRECTION 0x38 #define MAPPED_X(x, y) (x) #define MAPPED_Y(x, y) (y) #endif //#define SPI3 //9-bit 3-wire SPI (SSI2) mode (SCLK, SDA, SCS) // Default setting for the BOOSTXL-K350QVG-S1 // Need to remove the "R10" (connect the "PB7/SSI2Tx" to "PD1/AIN6_TOUCH_XP") on Launchpad #define SPI4 //8-bit 4-wire SPI (SSI2) mode (SCLK, SDA, SCS, SDC) // Need to remove the "R10" (connect the "PB7/SSI2Tx" to "PD1/AIN6_TOUCH_XP") on Launchpad // Need to move the "R2" to "R3" position, // and move "R8" to "R9" position on the BOOSTXL-K350QVG-S1 //***************************************************************************** // // Defines for the pins that are used to communicate with the SSD2119. // //***************************************************************************** #define LCD_CS_PERIPH SYSCTL_PERIPH_GPIOA #define LCD_CS_BASE GPIO_PORTA_BASE #define LCD_CS_PIN GPIO_PIN_4 #define LCD_DC_PERIPH SYSCTL_PERIPH_GPIOA #define LCD_DC_BASE GPIO_PORTA_BASE #define LCD_DC_PIN GPIO_PIN_5 #define LCD_RST_PERIPH SYSCTL_PERIPH_GPIOD #define LCD_RST_BASE GPIO_PORTD_BASE #define LCD_RST_PIN GPIO_PIN_7 #define LCD_LED_PERIPH SYSCTL_PERIPH_GPIOF #define LCD_LED_BASE GPIO_PORTF_BASE #define LCD_LED_PIN GPIO_PIN_2 //***************************************************************************** // // The dimensions of the LCD panel. // //***************************************************************************** #define LCD_VERTICAL_MAX 240 #define LCD_HORIZONTAL_MAX 320 #define SSD2119_ENTRY_MODE_REG 0x11 #define SSD2119_RAM_DATA_REG 0x22 #define SSD2119_V_RAM_POS_REG 0x44 #define SSD2119_H_RAM_START_REG 0x45 #define SSD2119_H_RAM_END_REG 0x46 #define SSD2119_X_RAM_ADDR_REG 0x4E #define SSD2119_Y_RAM_ADDR_REG 0x4F #define ENTRY_MODE_DEFAULT 0x6830 #define MAKE_ENTRY_MODE(x) ((ENTRY_MODE_DEFAULT & 0xFF00) | (x)) //***************************************************************************** // // 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)) //***************************************************************************** // // Macro used to set the LCD data bus in preparation for writing a byte to the // device. // //***************************************************************************** uint16_t pui16Data[2]; #ifdef SPI3 //***************************************************************************** // Writes a data word to the SSD2119. This function implements the 3-wire SPI // interface to the LCD display. //***************************************************************************** static void WriteDataSPI(unsigned short usData) { pui16Data[0] = 0x100 | (usData >> 8);// set the most significant byte of the data. pui16Data[1] = 0x100 | usData;// set the least significant byte of the data. HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = 0;//CS="0" SSIDataPut(SSI2_BASE, pui16Data[0]); SSIDataPut(SSI2_BASE, pui16Data[1]); while(SSIBusy(SSI2_BASE)){ } // Wait until SSI0 is done transferring all the data in the transmit FIFO. HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = LCD_CS_PIN; } //***************************************************************************** // Writes register word to the SSD2119. This function implements the 3-wire SPI // interface to the LCD display. //***************************************************************************** static void WriteCommandSPI(unsigned short usData) { pui16Data[0] = 0;// set the most significant byte of the data. pui16Data[1] = 0xFF & usData;// set the least significant byte of the data. HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = 0;//CS="0" SSIDataPut(SSI2_BASE, pui16Data[0]); SSIDataPut(SSI2_BASE, pui16Data[1]); while(SSIBusy(SSI2_BASE)){ } // Wait until SSI0 is done transferring all the data in the transmit FIFO. HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = LCD_CS_PIN; } #endif #ifdef SPI4 //***************************************************************************** // Writes a data word to the SSD2119. This function implements the 4-wire SPI // interface to the LCD display. //***************************************************************************** static void WriteDataSPI(unsigned short usData) { pui16Data[0] = (usData >> 8);// Write the most significant byte of the data to the bus. pui16Data[1] = usData;// Write the least significant byte of the data to the bus. HWREG(LCD_DC_BASE + GPIO_O_DATA + (LCD_DC_PIN << 2)) = LCD_DC_PIN;//DC="1" HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = 0;//CS="0" SSIDataPut(SSI2_BASE, pui16Data[0]); SSIDataPut(SSI2_BASE, pui16Data[1]); while(SSIBusy(SSI2_BASE)){ } // Wait until SSI0 is done transferring all the data in the transmit FIFO. HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = LCD_CS_PIN; } //***************************************************************************** // Writes register word to the SSD2119. This function implements the 3-wire SPI // interface to the LCD display. //***************************************************************************** static void WriteCommandSPI(unsigned short usData) { pui16Data[0] = 0;// Write the most significant byte of the data to the bus. pui16Data[1] = usData;// Write the least significant byte of the data to the bus. HWREG(LCD_DC_BASE + GPIO_O_DATA + (LCD_DC_PIN << 2)) = 0;//DC="0" HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = 0;//CS="0" SSIDataPut(SSI2_BASE, pui16Data[0]); SSIDataPut(SSI2_BASE, pui16Data[1]); while(SSIBusy(SSI2_BASE)){ } // Wait until SSI0 is done transferring all the data in the transmit FIFO. HWREG(LCD_CS_BASE + GPIO_O_DATA + (LCD_CS_PIN << 2)) = LCD_CS_PIN; } #endif //***************************************************************************** // Initializes the LCD interface. // Enable the SSI2 for LCD data/register transfer. // Set the LCD_CS_PIN, LCD_DC_PIN, LCD_RST_PIN. //***************************************************************************** static void LCD_PORT_Init(void) { uint32_t pui32DataRx[3]; // The SSI2 peripheral must be enabled for use. SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2); // For this example SSI2 is used with PortB[7:4]. The actual port and pins // used may be different on your part, consult the data sheet for more // information. GPIO port B needs to be enabled so these pins can be used. // TODO: change this to whichever GPIO port you are using. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // Enable the PortA[5:4] for the LCD_SCS, LCD_SDC // Enable the PortD[7] for LCD_RST // Enable the PortF[2] for LED backlight SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // Change PD7 into GPIO output. HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) |= GPIO_LOCK_KEY; HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= 0x80; HWREG(GPIO_PORTD_BASE + GPIO_O_AFSEL) &= 0x7f; GPIOPinTypeGPIOOutput(LCD_RST_BASE, LCD_RST_PIN); GPIOPinTypeGPIOOutput(LCD_CS_BASE, LCD_CS_PIN); GPIOPinTypeGPIOOutput(LCD_DC_BASE, LCD_DC_PIN); GPIOPinTypeGPIOOutput(LCD_LED_BASE, LCD_LED_PIN); //GPIOPadConfigSet(LCD_LED_BASE, LCD_LED_PIN, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD); // Configure the pin muxing for SSI2 functions on port B4, B5, B6, and B7. // This step is not necessary if your part does not support pin muxing. // TODO: change this to select the port/pin you are using. GPIOPinConfigure(GPIO_PB4_SSI2CLK); GPIOPinConfigure(GPIO_PB5_SSI2FSS); GPIOPinConfigure(GPIO_PB6_SSI2RX); GPIOPinConfigure(GPIO_PB7_SSI2TX); // Configure the GPIO settings for the SSI pins. This function also gives // control of these pins to the SSI hardware. Consult the data sheet to // see which functions are allocated per pin. // The pins are assigned as follows: // PB7 - SSI2Tx // PB6 - SSI2Rx // PB5 - SSI2Fss // PB4 - SSI2CLK // TODO: change this to select the port/pin you are using. GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5 | GPIO_PIN_4); GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_7, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD); // Configure and enable the SSI port for SPI master mode. Use SSI0, // system clock supply, idle clock level low and active low clock in // freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data. // For SPI mode, you can set the polarity of the SSI clock when the SSI // unit is idle. You can also configure what clock edge you want to // capture data on. Please reference the datasheet for more information on // the different SPI modes. #ifdef SPI3 SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 20000000, 9); #endif #ifdef SPI4 SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 20000000, 8); #endif // Enable the SSI2 module. SSIEnable(SSI2_BASE); // Read any residual data from the SSI port. This makes sure the receive // FIFOs are empty, so we don't read any unwanted junk. This is done here // because the SPI SSI mode is full-duplex, which allows you to send and // receive at the same time. The SSIDataGetNonBlocking function returns // "true" when data was returned, and "false" when no data was returned. // The "non-blocking" function checks if there is any data in the receive // FIFO and does not "hang" if there isn't. while(SSIDataGetNonBlocking(SSI2_BASE, &pui32DataRx[0])) { } } void LED_backlight_ON(void) { HWREG(LCD_LED_BASE + GPIO_O_DATA + (LCD_LED_PIN << 2)) = LCD_LED_PIN; } void LED_backlight_OFF(void) { HWREG(LCD_LED_BASE + GPIO_O_DATA + (LCD_LED_PIN << 2)) = 0; } //***************************************************************************** // //! Initializes the display driver. //! //! This function initializes the SSD2119 display controller on the panel, //! preparing it to display data. //! //! \return None. // //***************************************************************************** void Kentec320x240x16_SSD2119Init(void) { unsigned int ulClockMS, ulCount; // Get the current processor clock frequency. ulClockMS = SysCtlClockGet() / (3 * 1000); // Initializes the LCD port LCD_PORT_Init(); // Reset the LCD HWREG(LCD_RST_BASE + GPIO_O_DATA + (LCD_RST_PIN << 2)) = 0;//RST="0" SysCtlDelay(10 * ulClockMS); HWREG(LCD_RST_BASE + GPIO_O_DATA + (LCD_RST_PIN << 2)) = LCD_RST_PIN;//RST="1" SysCtlDelay(20 * ulClockMS); // Enter sleep mode (if we are not already there). WriteCommandSPI(0x10);//SLEEP_MODE_REG WriteDataSPI(0x0001); // // Set initial power parameters. // WriteCommandSPI(0x1E);//SSD2119_PWR_CTRL_5_REG WriteDataSPI(0x00BA); WriteCommandSPI(0x28);//SSD2119_VCOM_OTP_1_REG WriteDataSPI(0x0006); // // Start the oscillator. // WriteCommandSPI(0x00); WriteDataSPI(0x0001); // // Set pixel format and basic display orientation (scanning direction). // WriteCommandSPI(0x01); WriteDataSPI(0x30EF); WriteCommandSPI(0x02); WriteDataSPI(0x0600); // // Exit sleep mode. // WriteCommandSPI(0x10);//SSD2119_SLEEP_MODE_REG WriteDataSPI(0x0000); // // Delay 30mS // SysCtlDelay(30 * ulClockMS); // // Configure pixel color format and MCU interface parameters. // WriteCommandSPI(SSD2119_ENTRY_MODE_REG); WriteDataSPI(ENTRY_MODE_DEFAULT); // // Enable the display. // WriteCommandSPI(0x07); WriteDataSPI(0x0033); // // Set VCIX2 voltage to 6.1V. // WriteCommandSPI(0x0C);//SSD2119_PWR_CTRL_2_REG WriteDataSPI(0x0005); // // Configure gamma correction. // WriteCommandSPI(0x30); WriteDataSPI(0x0000);//SSD2119_GAMMA_CTRL_1 WriteCommandSPI(0x31); WriteDataSPI(0x0400);//SSD2119_GAMMA_CTRL_2 WriteCommandSPI(0x32); WriteDataSPI(0x0106);//SSD2119_GAMMA_CTRL_3 WriteCommandSPI(0x33); WriteDataSPI(0x0700);//SSD2119_GAMMA_CTRL_4 WriteCommandSPI(0x34); WriteDataSPI(0x0002);//SSD2119_GAMMA_CTRL_5 WriteCommandSPI(0x35); WriteDataSPI(0x0702);//SSD2119_GAMMA_CTRL_6 WriteCommandSPI(0x36); WriteDataSPI(0x0707);//SSD2119_GAMMA_CTRL_7 WriteCommandSPI(0x37); WriteDataSPI(0x0203);//SSD2119_GAMMA_CTRL_8 WriteCommandSPI(0x3A); WriteDataSPI(0x1400);//SSD2119_GAMMA_CTRL_9 WriteCommandSPI(0x3B); WriteDataSPI(0x0F03);//SSD2119_GAMMA_CTRL_10 // // Configure Vlcd63 and VCOMl. // WriteCommandSPI(0x0D);//SSD2119_PWR_CTRL_3_REG WriteDataSPI(0x0007); WriteCommandSPI(0x0E);//SSD2119_PWR_CTRL_4_REG WriteDataSPI(0x3100); // // Set the display size and ensure that the GRAM window is set to allow // access to the full display buffer. // WriteCommandSPI(SSD2119_V_RAM_POS_REG); WriteDataSPI((LCD_VERTICAL_MAX-1) << 8); WriteCommandSPI(SSD2119_H_RAM_START_REG); WriteDataSPI(0x0000); WriteCommandSPI(SSD2119_H_RAM_END_REG); WriteDataSPI(LCD_HORIZONTAL_MAX-1); WriteCommandSPI(SSD2119_X_RAM_ADDR_REG); WriteDataSPI(0x00); WriteCommandSPI(SSD2119_Y_RAM_ADDR_REG); WriteDataSPI(0x00); // Clear the contents of the display buffer. WriteCommandSPI(SSD2119_RAM_DATA_REG); for(ulCount = 0; ulCount < (320 * 240); ulCount++) { WriteDataSPI(0x0000); } LED_backlight_ON(); } //***************************************************************************** // //! 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 Kentec320x240x16_SSD2119PixelDraw(void *pvDisplayData, int lX, int lY, unsigned int ulValue) { // // Set the X address of the display cursor. // WriteCommandSPI(SSD2119_X_RAM_ADDR_REG); WriteDataSPI(MAPPED_X(lX, lY)); // // Set the Y address of the display cursor. // WriteCommandSPI(SSD2119_Y_RAM_ADDR_REG); WriteDataSPI(MAPPED_Y(lX, lY)); // // Write the pixel value. // WriteCommandSPI(SSD2119_RAM_DATA_REG); WriteDataSPI(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 Kentec320x240x16_SSD2119PixelDrawMultiple(void *pvDisplayData, int lX, int lY, int lX0, int lCount, int lBPP, const unsigned char *pucData, const unsigned char *pucPalette) { unsigned int ulByte; // // Set the cursor increment to left to right, followed by top to bottom. // WriteCommandSPI(SSD2119_ENTRY_MODE_REG); WriteDataSPI(MAKE_ENTRY_MODE(HORIZ_DIRECTION)); // // Set the starting X address of the display cursor. // WriteCommandSPI(SSD2119_X_RAM_ADDR_REG); WriteDataSPI(MAPPED_X(lX, lY)); // // Set the Y address of the display cursor. // WriteCommandSPI(SSD2119_Y_RAM_ADDR_REG); WriteDataSPI(MAPPED_Y(lX, lY)); // // Write the data RAM write command. // WriteCommandSPI(SSD2119_RAM_DATA_REG); // // 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. // WriteDataSPI(((unsigned int *)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 // http://en.wikipedia.org/wiki/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 int *)(pucPalette + ulByte) & 0x00ffffff); // // Translate this palette entry and write it to the // screen. // WriteDataSPI(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 int *)(pucPalette + ulByte) & 0x00ffffff); // // Translate this palette entry and write it to the // screen. // WriteDataSPI(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 int *)(pucPalette + ulByte) & 0x00ffffff; // // Translate this palette entry and write it to the screen. // WriteDataSPI(DPYCOLORTRANSLATE(ulByte)); } // // The image data has been drawn. // break; } // // We are being passed data in the display's native format. Merely // write it directly to the display. This is a special case which is // not used by the graphics library but which is helpful to // applications which may want to handle, for example, JPEG images. // case 16: { unsigned short usByte; // // 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. // usByte = *((unsigned short *)pucData); pucData += 2; // // Translate this palette entry and write it to the screen. // WriteDataSPI(usByte); } } } } //***************************************************************************** // //! 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 Kentec320x240x16_SSD2119LineDrawH(void *pvDisplayData, int lX1, int lX2, int lY, unsigned int ulValue) { // // Set the cursor increment to left to right, followed by top to bottom. // WriteCommandSPI(SSD2119_ENTRY_MODE_REG); WriteDataSPI(MAKE_ENTRY_MODE(HORIZ_DIRECTION)); // // Set the starting X address of the display cursor. // WriteCommandSPI(SSD2119_X_RAM_ADDR_REG); WriteDataSPI(MAPPED_X(lX1, lY)); // // Set the Y address of the display cursor. // WriteCommandSPI(SSD2119_Y_RAM_ADDR_REG); WriteDataSPI(MAPPED_Y(lX1, lY)); // // Write the data RAM write command. // WriteCommandSPI(SSD2119_RAM_DATA_REG); // // Loop through the pixels of this horizontal line. // while(lX1++ <= lX2) { // // Write the pixel value. // WriteDataSPI(ulValue); } } //***************************************************************************** // //! 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 Kentec320x240x16_SSD2119LineDrawV(void *pvDisplayData, int lX, int lY1, int lY2, unsigned int ulValue) { // // Set the cursor increment to top to bottom, followed by left to right. // WriteCommandSPI(SSD2119_ENTRY_MODE_REG); WriteDataSPI(MAKE_ENTRY_MODE(VERT_DIRECTION)); // // Set the X address of the display cursor. // WriteCommandSPI(SSD2119_X_RAM_ADDR_REG); WriteDataSPI(MAPPED_X(lX, lY1)); // // Set the starting Y address of the display cursor. // WriteCommandSPI(SSD2119_Y_RAM_ADDR_REG); WriteDataSPI(MAPPED_Y(lX, lY1)); // // Write the data RAM write command. // WriteCommandSPI(SSD2119_RAM_DATA_REG); // // Loop through the pixels of this vertical line. // while(lY1++ <= lY2) { // // Write the pixel value. // WriteDataSPI(ulValue); } } //***************************************************************************** // //! 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 Kentec320x240x16_SSD2119RectFill(void *pvDisplayData, const tRectangle *pRect, unsigned int ulValue) { int lCount; // // Write the Y extents of the rectangle. // WriteCommandSPI(SSD2119_ENTRY_MODE_REG); WriteDataSPI(MAKE_ENTRY_MODE(HORIZ_DIRECTION)); // // Write the X extents of the rectangle. // WriteCommandSPI(SSD2119_H_RAM_START_REG); #if (defined PORTRAIT) || (defined LANDSCAPE) WriteDataSPI(MAPPED_X(pRect->i16XMax, pRect->i16YMax)); #else WriteDataSPI(MAPPED_X(pRect->i16XMin, pRect->i16YMin)); #endif WriteCommandSPI(SSD2119_H_RAM_END_REG); #if (defined PORTRAIT) || (defined LANDSCAPE) WriteDataSPI(MAPPED_X(pRect->i16XMin, pRect->i16YMin)); #else WriteDataSPI(MAPPED_X(pRect->i16XMax, pRect->i16YMax)); #endif // // Write the Y extents of the rectangle // WriteCommandSPI(SSD2119_V_RAM_POS_REG); #if (defined LANDSCAPE_FLIP) || (defined PORTRAIT) WriteDataSPI(MAPPED_Y(pRect->i16XMin, pRect->i16YMin) | (MAPPED_Y(pRect->i16XMax, pRect->i16YMax) << 8)); #else WriteDataSPI(MAPPED_Y(pRect->i16XMax, pRect->i16YMax) | (MAPPED_Y(pRect->i16XMin, pRect->i16YMin) << 8)); #endif // // Set the display cursor to the upper left of the rectangle (in application // coordinate space). // WriteCommandSPI(SSD2119_X_RAM_ADDR_REG); WriteDataSPI(MAPPED_X(pRect->i16XMin, pRect->i16YMin)); WriteCommandSPI(SSD2119_Y_RAM_ADDR_REG); WriteDataSPI(MAPPED_Y(pRect->i16XMin, pRect->i16YMin)); // // Tell the controller we are about to write data into its RAM. // WriteCommandSPI(SSD2119_RAM_DATA_REG); // // Loop through the pixels of this filled rectangle. // for(lCount = ((pRect->i16XMax - pRect->i16XMin + 1) * (pRect->i16YMax - pRect->i16YMin + 1)); lCount >= 0; lCount--) { // // Write the pixel value. // WriteDataSPI(ulValue); } // // Reset the X extents to the entire screen. // WriteCommandSPI(SSD2119_H_RAM_START_REG); WriteDataSPI(0x0000); WriteCommandSPI(SSD2119_H_RAM_END_REG); WriteDataSPI(0x013F); // // Reset the Y extent to the full screen // WriteCommandSPI(SSD2119_V_RAM_POS_REG); WriteDataSPI(0xEF00); } //***************************************************************************** // //! 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 unsigned int Kentec320x240x16_SSD2119ColorTranslate(void *pvDisplayData, unsigned int 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 SSD2119 //! driver, the flush is a no operation. //! //! \return None. // //***************************************************************************** static void Kentec320x240x16_SSD2119Flush(void *pvDisplayData) { // // There is nothing to be done. // } //***************************************************************************** // //! The display structure that describes the driver for the Kentec //! K350QVG-V2-F TFT panel with an SSD2119 controller. // //***************************************************************************** const tDisplay g_sKentec320x240x16_SSD2119 = { sizeof(tDisplay), 0, #if defined(PORTRAIT) || defined(PORTRAIT_FLIP) 240, 320, #else 320, 240, #endif Kentec320x240x16_SSD2119PixelDraw, Kentec320x240x16_SSD2119PixelDrawMultiple, Kentec320x240x16_SSD2119LineDrawH, Kentec320x240x16_SSD2119LineDrawV, Kentec320x240x16_SSD2119RectFill, Kentec320x240x16_SSD2119ColorTranslate, Kentec320x240x16_SSD2119Flush }; //***************************************************************************** // // Close the Doxygen group. //! @} // //*****************************************************************************