SAMV71 Xplained Ultra Software Package 1.4

ili9488_spi.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 
00030 /**
00031  * \file
00032  *
00033  * Implementation of ILI9488 driver.
00034  *
00035  */
00036 
00037 /*----------------------------------------------------------------------------
00038  *        Headers
00039  *----------------------------------------------------------------------------*/
00040 #include "board.h"
00041 #include <string.h>
00042 #include <stdio.h>
00043 
00044 #ifdef BOARD_LCD_ILI9488
00045 
00046 #define ILI9488_SPI     SPI0
00047 
00048 /*----------------------------------------------------------------------------
00049  *        Local variables
00050  *----------------------------------------------------------------------------*/
00051 
00052 /** Pio pins to configure. */
00053 static const Pin lcd_spi_reset_pin = LCD_SPI_PIN_RESET;
00054 static const Pin lcd_spi_pwm_pin = BOARD_SPI_LCD_PIN_BACKLIGHT;
00055 /** Pins to configure for the application. */
00056 static const Pin lcd_pins[] = BOARD_SPI_LCD_PINS;
00057 /** Pins to configure for the application. */
00058 static const Pin lcd_spi_cds_pin = BOARD_SPI_LCD_PIN_CDS;
00059 
00060 /*----------------------------------------------------------------------------
00061  *        Local functions
00062  *----------------------------------------------------------------------------*/
00063 /**
00064  * \brief ILI9488 Hardware Initialization for SPI/SMC LCD.
00065  */
00066 static void _ILI9488_Spi_HW_Initialize(void) 
00067 {
00068     /* Pin configurations */
00069     PIO_Configure(&lcd_spi_reset_pin, 1);
00070     PIO_Configure(&lcd_spi_cds_pin, 1);
00071     PIO_Configure(lcd_pins, PIO_LISTSIZE(lcd_pins));
00072     PIO_Configure(&lcd_spi_pwm_pin, 1);
00073 
00074     /* Enable PWM peripheral clock */
00075     PMC_EnablePeripheral(ID_PWM0);
00076     PMC_EnablePeripheral(ID_SPI0);
00077     /* Set clock A and clock B */
00078     // set for 14.11 KHz for CABC control
00079     //mode = PWM_CLK_PREB(0x0A) | (PWM_CLK_DIVB(110)) |
00080     //PWM_CLK_PREA(0x0A) | (PWM_CLK_DIVA(110));
00081     PWMC_ConfigureClocks(PWM0, 14200, 0,  BOARD_MCK);
00082 
00083     /* Configure PWM channel 1 for LED0  */
00084     PWMC_DisableChannel(PWM0, CHANNEL_PWM_LCD);
00085 
00086     PWMC_ConfigureChannel(PWM0, CHANNEL_PWM_LCD, PWM_CMR_CPRE_CLKA,0,
00087                 PWM_CMR_CPOL);
00088     PWMC_SetPeriod(PWM0, CHANNEL_PWM_LCD, 16);
00089     PWMC_SetDutyCycle(PWM0, CHANNEL_PWM_LCD, 8);
00090     PWMC_EnableChannel(PWM0, CHANNEL_PWM_LCD);
00091 
00092     SPI_Configure(ILI9488_SPI, ID_SPI0, (SPI_MR_MSTR | SPI_MR_MODFDIS 
00093             | SPI_PCS( SMC_EBI_LCD_CS )));
00094     SPI_ConfigureNPCS(ILI9488_SPI, 
00095                     SMC_EBI_LCD_CS,
00096                     SPI_CSR_CPOL | SPI_CSR_BITS_8_BIT | SPI_DLYBS(6, BOARD_MCK)
00097                     |SPI_DLYBCT(100, BOARD_MCK) |SPI_SCBR( 20000000, BOARD_MCK));
00098     SPI_Enable(ILI9488_SPI);
00099 }
00100 
00101 /*----------------------------------------------------------------------------
00102  *        Exported functions
00103  *----------------------------------------------------------------------------*/
00104 uint32_t ILI9488_SpiReadChipId (void)
00105 {
00106     uint32_t chipid = 0;
00107     uint32_t chipidBuf[2];
00108     uint8_t i, reg, param;
00109     
00110     reg = 0x81;
00111     param = 0x0;
00112     for (i = 3; i > 0; i--) {
00113         
00114         ILI9488_SpiSendCommand(ILI9488_CMD_SPI_READ_SETTINGS, &reg, 0, AccessWrite, 1);
00115         reg++;
00116         ILI9488_SpiSendCommand(ILI9488_CMD_READ_ID4, 0, 0, AccessInst, 0);
00117         ILI9488_SpiSendCommand(0, 0, chipidBuf, AccessRead, 2);
00118         chipid |= (chipidBuf[1] & 0xFF) << ((i - 1) << 3);
00119         ILI9488_SpiSendCommand(ILI9488_CMD_SPI_READ_SETTINGS, &param, 0, AccessWrite, 1);
00120     }
00121     return chipid;
00122 }
00123  
00124 /**
00125  * \brief Set ILI9488 Pixel Format in SPI/SMC mode.
00126  * \param format Format of pixel
00127  */
00128 void ILI9488_SpiSetPixelFormat(uint8_t format)
00129 {
00130     ILI9488_SpiSendCommand(ILI9488_CMD_COLMOD_PIXEL_FORMAT_SET, &format, 0, AccessWrite, 1);
00131 }
00132 
00133 /**
00134  * \brief Initialize the ILI9488 controller in SPI/SMC mode.
00135  */
00136 uint32_t ILI9488_SpiInitialize( sXdmad * dmad )
00137 {
00138     uint32_t chipid = 0;
00139     uint8_t param;
00140     
00141     _ILI9488_Spi_HW_Initialize();
00142     ILI9488_SpiInitializeWithDma(dmad);
00143 
00144     ILI9488_SpiSendCommand(ILI9488_CMD_SOFTWARE_RESET, 0, 0, AccessInst, 0);
00145     Wait(200);
00146 
00147     ILI9488_SpiSendCommand(ILI9488_CMD_SLEEP_OUT, 0, 0, AccessInst, 0);
00148     Wait(200);
00149 
00150     // make it tRGB and reverse the column order
00151     param = 0x48;
00152     ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_ACCESS_CONTROL,&param, 0, AccessWrite, 1);
00153     Wait(100);
00154 
00155     param = 0x04;
00156     ILI9488_SpiSendCommand(ILI9488_CMD_CABC_CONTROL_9, &param, 0, AccessWrite, 1);
00157     
00158     if ( (chipid = ILI9488_SpiReadChipId()) != ILI9488_DEVICE_CODE ) {
00159         printf( "Read ILI9488 chip ID (0x%04x) error, skip initialization.\r\n",
00160                         (unsigned int)chipid ) ;
00161         return 1 ;
00162     }
00163     ILI9488_SpiSetPixelFormat(6);
00164     ILI9488_SpiSendCommand(ILI9488_CMD_NORMAL_DISP_MODE_ON, 0, 0, AccessInst, 0);
00165     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_ON, 0, 0, AccessInst, 0);
00166     return 0 ;
00167 }
00168 
00169 /**
00170  * \brief ILI9488 configure cursor in SPI/SMC mode.
00171  * \Param x X position.
00172  * \Param y Y position.
00173  */
00174 void ILI9488_SpiSetCursor(uint16_t x, uint16_t y)
00175 {
00176     /* Set Horizontal Address Start Position */
00177     uint32_t cnt = 0;
00178 
00179     uint8_t buf[4];
00180     cnt = sizeof(buf);
00181     buf[0] = get_8b_to_16b(x);
00182     buf[1] = get_0b_to_8b(x);
00183     x+=1;
00184     buf[2] = get_8b_to_16b(x);
00185     buf[3] = get_0b_to_8b(x);
00186     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00187     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00188 
00189     /* Set Horizontal Address End Position */
00190     buf[0] = get_8b_to_16b(y);
00191     buf[1] = get_0b_to_8b(y);
00192     y+=1;
00193     buf[2] = get_8b_to_16b(y);
00194     buf[3] = get_0b_to_8b(y);
00195     ILI9488_SpiSendCommand(ILI9488_CMD_PAGE_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00196     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00197 }
00198 
00199 /**
00200  * \brief ILI9488 configure window.
00201  * \Param dwX X start position.
00202  * \Param dwX Y start position.
00203  * \Param dwWidth  Width of window.
00204  * \Param dwHeight Height of window.
00205  */
00206 void ILI9488_SpiSetWindow( uint16_t dwX, uint16_t dwY, uint16_t dwWidth, 
00207                 uint16_t dwHeight )
00208 {
00209     uint16_t ColStart, ColEnd, RowStart, RowEnd;
00210     uint32_t cnt = 0;
00211     uint8_t buf[4];
00212     cnt = sizeof(buf);
00213     ColStart  =  dwX ;
00214     ColEnd    =  dwWidth + dwX;
00215 
00216     RowStart = dwY ;
00217     RowEnd   = dwHeight + dwY;
00218 
00219     buf[0] = get_8b_to_16b(ColStart);
00220     buf[1] = get_0b_to_8b(ColStart);
00221     buf[2] = get_8b_to_16b(ColEnd);
00222     buf[3] = get_0b_to_8b(ColEnd);
00223     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00224     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00225 
00226     /* Set Horizontal Address End Position */
00227     buf[0] = get_8b_to_16b(RowStart);
00228     buf[1] = get_0b_to_8b(RowStart);
00229     buf[2] = get_8b_to_16b(RowEnd);
00230     buf[3] = get_0b_to_8b(RowEnd);
00231     ILI9488_SpiSendCommand(ILI9488_CMD_PAGE_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00232     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00233 }
00234 
00235 /**
00236  * \brief ILI9488 configure window with full size.
00237  */
00238 void ILI9488_SpiSetFullWindow(void)
00239 {
00240     uint16_t c_start,c_end,r_start,r_end;
00241     uint32_t cnt = 0;
00242     uint8_t buf[4];
00243     cnt = sizeof(buf);
00244     c_start =  0 ;
00245     c_end =  ILI9488_LCD_WIDTH - 1;
00246 
00247     r_start = 0 ;
00248     r_end   = ILI9488_LCD_HEIGHT - 1;
00249 
00250     /* Set Horizontal Address Start Position */
00251     buf[0] = get_8b_to_16b(c_start);
00252     buf[1] = get_0b_to_8b(c_start);
00253     buf[2] = get_8b_to_16b(c_end);
00254     buf[3] = get_0b_to_8b(c_end);
00255     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00256     ILI9488_SpiSendCommand(ILI9488_CMD_NOP ,0, 0, AccessInst, 0);
00257 
00258     /* Set Horizontal Address End Position */
00259     buf[0] = get_8b_to_16b(r_start);
00260     buf[1] = get_0b_to_8b(r_start);
00261     buf[2] = get_8b_to_16b(r_end);
00262     buf[3] = get_0b_to_8b(r_end);
00263     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00264     ILI9488_SpiSendCommand(ILI9488_CMD_NOP ,0, 0, AccessInst, 0);
00265 }
00266 
00267 /**
00268  * \brief Turn on the ILI9488.
00269  */
00270 void ILI9488_SpiOn( void )
00271 {
00272     ILI9488_SpiSendCommand(ILI9488_CMD_PIXEL_OFF, 0, 0, AccessInst, 0);
00273     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_ON, 0, 0, AccessInst, 0);
00274     ILI9488_SpiSendCommand(ILI9488_CMD_NORMAL_DISP_MODE_ON, 0, 0, AccessInst, 0);
00275 }
00276 
00277 /**
00278  * \brief Turn off the ILI9488.
00279  */
00280 void ILI9488_SpiOff( void )
00281 {
00282     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_OFF, 0, 0, AccessInst, 0);
00283 }
00284 
00285 /**
00286  * \brief ILI9488 configure landscape.
00287  * \Param dwRGB RGB mode.
00288  * \Param LandscaprMode Landscape Mode.
00289  */
00290 void ILI9488_SpiSetDisplayLandscape( uint8_t dwRGB, uint8_t LandscapeMode )
00291 {
00292     uint8_t value;
00293     if(LandscapeMode) {
00294         if(dwRGB) {
00295             value = 0xE8;
00296         } else {
00297             value = 0xE0;
00298         }
00299     } else {
00300         if(dwRGB) {
00301             value = 0x48;
00302         } else {
00303             value = 0x40;
00304         }
00305     }
00306     ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_ACCESS_CONTROL, &value, 0, AccessWrite, sizeof(value));
00307 }
00308 
00309 /**
00310  * \brief Send single command to ILI9488
00311  * \param cmd  command.
00312  */
00313 static void ILI9488_SendCmd( uint8_t cmd )
00314 {
00315     uint32_t i;
00316     PIO_Clear(&lcd_spi_cds_pin);
00317     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, cmd);  
00318     for(i = 0; i<0x18; i++);
00319 }
00320 
00321 /**
00322  * \brief Draw a pixel on LCD with given color, DMA not used
00323  * \param x  X-coordinate of pixel.
00324  * \param y  Y-coordinate of pixel.
00325  * \param color  Pixel color.
00326  */
00327 void ILI9488_SetPixelColor(uint32_t x, uint32_t y, uint32_t color)
00328 {
00329     uint32_t i;
00330 
00331     /* Set Horizontal Address Start Position */
00332     ILI9488_SendCmd(ILI9488_CMD_COLUMN_ADDRESS_SET);    
00333     PIO_Set(&lcd_spi_cds_pin);
00334     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(x));
00335     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(x));
00336     x++;
00337     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(x));
00338     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(x));
00339     for(i = 0; i<0x18; i++);
00340 
00341     ILI9488_SendCmd(ILI9488_CMD_NOP);
00342 
00343     /* Set Horizontal Address End Position */
00344     ILI9488_SendCmd(ILI9488_CMD_PAGE_ADDRESS_SET);
00345     PIO_Set(&lcd_spi_cds_pin);
00346     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(y));
00347     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(y));
00348     y++;
00349     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(y));
00350     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(y));
00351     for(i = 0; i<0x18; i++);
00352 
00353     ILI9488_SendCmd(ILI9488_CMD_NOP);
00354 
00355     /* Set Color */
00356     ILI9488_SendCmd(ILI9488_CMD_MEMORY_WRITE);
00357     PIO_Set(&lcd_spi_cds_pin);
00358     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_16b_to_24b(color));
00359     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(color));
00360     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(color));
00361 
00362     for(i = 0; i<0x18; i++);
00363 }
00364 
00365 #endif
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines