SAMV71 Xplained Ultra Software Package 1.3

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 /*----------------------------------------------------------------------------
00047  *        Local variables
00048  *----------------------------------------------------------------------------*/
00049 
00050 /** Pio pins to configure. */
00051 static const Pin lcd_spi_reset_pin = LCD_SPI_PIN_RESET;
00052 static const Pin lcd_spi_pwm_pin = BOARD_SPI_LCD_PIN_BACKLIGHT;
00053 /** Pins to configure for the application. */
00054 static const Pin lcd_pins[] = BOARD_SPI_LCD_PINS;
00055 /** Pins to configure for the application. */
00056 static const Pin lcd_spi_cds_pin = BOARD_SPI_LCD_PIN_CDS;
00057 
00058 /*----------------------------------------------------------------------------
00059  *        Local functions
00060  *----------------------------------------------------------------------------*/
00061 /**
00062  * \brief ILI9488 Hardware Initialization for SPI/SMC LCD.
00063  */
00064 static void _ILI9488_Spi_HW_Initialize(void) 
00065 {
00066     /* Pin configurations */
00067     PIO_Configure(&lcd_spi_reset_pin, 1);
00068     PIO_Configure(&lcd_spi_cds_pin, 1);
00069     PIO_Configure(lcd_pins, PIO_LISTSIZE(lcd_pins));
00070     PIO_Configure(&lcd_spi_pwm_pin, 1);
00071 
00072     /* Enable PWM peripheral clock */
00073     PMC_EnablePeripheral(ID_PWM0);
00074     PMC_EnablePeripheral(ID_SPI0);
00075     /* Set clock A and clock B */
00076     // set for 14.11 KHz for CABC control
00077     //mode = PWM_CLK_PREB(0x0A) | (PWM_CLK_DIVB(110)) |
00078     //PWM_CLK_PREA(0x0A) | (PWM_CLK_DIVA(110));
00079     PWMC_ConfigureClocks(PWM0, 14200, 0,  BOARD_MCK);
00080 
00081     /* Configure PWM channel 1 for LED0  */
00082     PWMC_DisableChannel(PWM0, CHANNEL_PWM_LCD);
00083 
00084     PWMC_ConfigureChannel(PWM0, CHANNEL_PWM_LCD, PWM_CMR_CPRE_CLKA,0,
00085                 PWM_CMR_CPOL);
00086     PWMC_SetPeriod(PWM0, CHANNEL_PWM_LCD, 16);
00087     PWMC_SetDutyCycle(PWM0, CHANNEL_PWM_LCD, 8);
00088     PWMC_EnableChannel(PWM0, CHANNEL_PWM_LCD);
00089 
00090     SPI_Configure(SPI0, ID_SPI0, (SPI_MR_MSTR | SPI_MR_MODFDIS 
00091             | SPI_PCS( SMC_EBI_LCD_CS )));
00092     SPI_ConfigureNPCS(SPI0, 
00093                     SMC_EBI_LCD_CS,
00094                     SPI_CSR_CPOL | SPI_CSR_BITS_8_BIT | SPI_DLYBS(6, BOARD_MCK)
00095                     |SPI_DLYBCT(100, BOARD_MCK) |SPI_SCBR( 20000000, BOARD_MCK));
00096     SPI_Enable(SPI0);
00097 }
00098 
00099 /*----------------------------------------------------------------------------
00100  *        Exported functions
00101  *----------------------------------------------------------------------------*/
00102 uint32_t ILI9488_SpiReadChipId (void)
00103 {
00104     uint32_t chipid = 0;
00105     uint32_t chipidBuf[2];
00106     uint8_t i, reg, param;
00107     
00108     reg = 0x81;
00109     param = 0x0;
00110     for (i = 3; i > 0; i--) {
00111         
00112         ILI9488_SpiSendCommand(ILI9488_CMD_SPI_READ_SETTINGS, &reg, 0, AccessWrite, 1);
00113         reg++;
00114         ILI9488_SpiSendCommand(ILI9488_CMD_READ_ID4, 0, 0, AccessInst, 0);
00115         ILI9488_SpiSendCommand(0, 0, chipidBuf, AccessRead, 2);
00116         chipid |= (chipidBuf[1] & 0xFF) << ((i - 1) << 3);
00117         ILI9488_SpiSendCommand(ILI9488_CMD_SPI_READ_SETTINGS, &param, 0, AccessWrite, 1);
00118     }
00119     return chipid;
00120 }
00121  
00122 /**
00123  * \brief Set ILI9488 Pixel Format in SPI/SMC mode.
00124  * \param format Format of pixel
00125  */
00126 void ILI9488_SpiSetPixelFormat(uint8_t format)
00127 {
00128     ILI9488_SpiSendCommand(ILI9488_CMD_COLMOD_PIXEL_FORMAT_SET, &format, 0, AccessWrite, 1);
00129 }
00130 
00131 /**
00132  * \brief Initialize the ILI9488 controller in SPI/SMC mode.
00133  */
00134 uint32_t ILI9488_SpiInitialize( sXdmad * dmad )
00135 {
00136     uint32_t chipid = 0;
00137     uint8_t param;
00138     
00139     _ILI9488_Spi_HW_Initialize();
00140     ILI9488_SpiInitializeWithDma(dmad);
00141 
00142     ILI9488_SpiSendCommand(ILI9488_CMD_SOFTWARE_RESET, 0, 0, AccessInst, 0);
00143     Wait(200);
00144 
00145     ILI9488_SpiSendCommand(ILI9488_CMD_SLEEP_OUT, 0, 0, AccessInst, 0);
00146     Wait(200);
00147 
00148     // make it tRGB and reverse the column order
00149     param = 0x48;
00150     ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_ACCESS_CONTROL,&param, 0, AccessWrite, 1);
00151     Wait(100);
00152 
00153     param = 0x04;
00154     ILI9488_SpiSendCommand(ILI9488_CMD_CABC_CONTROL_9, &param, 0, AccessWrite, 1);
00155     
00156     if ( (chipid = ILI9488_SpiReadChipId()) != ILI9488_DEVICE_CODE ) {
00157         printf( "Read ILI9488 chip ID (0x%04x) error, skip initialization.\r\n",
00158                         (unsigned int)chipid ) ;
00159         return 1 ;
00160     }
00161     ILI9488_SpiSetPixelFormat(6);
00162     ILI9488_SpiSendCommand(ILI9488_CMD_NORMAL_DISP_MODE_ON, 0, 0, AccessInst, 0);
00163     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_ON, 0, 0, AccessInst, 0);
00164     return 0 ;
00165 }
00166 
00167 /**
00168  * \brief ILI9488 configure cursor in SPI/SMC mode.
00169  * \Param x X position.
00170  * \Param y Y position.
00171  */
00172 void ILI9488_SpiSetCursor(uint16_t x, uint16_t y)
00173 {
00174     /* Set Horizontal Address Start Position */
00175     uint32_t cnt = 0;
00176 
00177     uint8_t buf[4];
00178     cnt = sizeof(buf);
00179     buf[0] = get_8b_to_16b(x);
00180     buf[1] = get_0b_to_8b(x);
00181     x+=1;
00182     buf[2] = get_8b_to_16b(x);
00183     buf[3] = get_0b_to_8b(x);
00184     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00185     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00186 
00187     /* Set Horizontal Address End Position */
00188     buf[0] = get_8b_to_16b(y);
00189     buf[1] = get_0b_to_8b(y);
00190     y+=1;
00191     buf[2] = get_8b_to_16b(y);
00192     buf[3] = get_0b_to_8b(y);
00193     ILI9488_SpiSendCommand(ILI9488_CMD_PAGE_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00194     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00195 }
00196 
00197 /**
00198  * \brief ILI9488 configure window.
00199  * \Param dwX X start position.
00200  * \Param dwX Y start position.
00201  * \Param dwWidth  Width of window.
00202  * \Param dwHeight Height of window.
00203  */
00204 void ILI9488_SpiSetWindow( uint16_t dwX, uint16_t dwY, uint16_t dwWidth, 
00205                 uint16_t dwHeight )
00206 {
00207     uint16_t ColStart, ColEnd, RowStart, RowEnd;
00208     uint32_t cnt = 0;
00209     uint8_t buf[4];
00210     cnt = sizeof(buf);
00211     ColStart  =  dwX ;
00212     ColEnd    =  dwWidth + dwX;
00213 
00214     RowStart = dwY ;
00215     RowEnd   = dwHeight + dwY;
00216 
00217     buf[0] = get_8b_to_16b(ColStart);
00218     buf[1] = get_0b_to_8b(ColStart);
00219     buf[2] = get_8b_to_16b(ColEnd);
00220     buf[3] = get_0b_to_8b(ColEnd);
00221     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00222     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00223 
00224     /* Set Horizontal Address End Position */
00225     buf[0] = get_8b_to_16b(RowStart);
00226     buf[1] = get_0b_to_8b(RowStart);
00227     buf[2] = get_8b_to_16b(RowEnd);
00228     buf[3] = get_0b_to_8b(RowEnd);
00229     ILI9488_SpiSendCommand(ILI9488_CMD_PAGE_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00230     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00231 }
00232 
00233 /**
00234  * \brief ILI9488 configure window with full size.
00235  */
00236 void ILI9488_SpiSetFullWindow(void)
00237 {
00238     uint16_t c_start,c_end,r_start,r_end;
00239     uint32_t cnt = 0;
00240     uint8_t buf[4];
00241     cnt = sizeof(buf);
00242     c_start =  0 ;
00243     c_end =  ILI9488_LCD_WIDTH - 1;
00244 
00245     r_start = 0 ;
00246     r_end   = ILI9488_LCD_HEIGHT - 1;
00247 
00248     /* Set Horizontal Address Start Position */
00249     buf[0] = get_8b_to_16b(c_start);
00250     buf[1] = get_0b_to_8b(c_start);
00251     buf[2] = get_8b_to_16b(c_end);
00252     buf[3] = get_0b_to_8b(c_end);
00253     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00254     ILI9488_SpiSendCommand(ILI9488_CMD_NOP ,0, 0, AccessInst, 0);
00255 
00256     /* Set Horizontal Address End Position */
00257     buf[0] = get_8b_to_16b(r_start);
00258     buf[1] = get_0b_to_8b(r_start);
00259     buf[2] = get_8b_to_16b(r_end);
00260     buf[3] = get_0b_to_8b(r_end);
00261     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t*)buf, 0, AccessWrite, cnt);
00262     ILI9488_SpiSendCommand(ILI9488_CMD_NOP ,0, 0, AccessInst, 0);
00263 }
00264 
00265 /**
00266  * \brief Turn on the ILI9488.
00267  */
00268 void ILI9488_SpiOn( void )
00269 {
00270     ILI9488_SpiSendCommand(ILI9488_CMD_PIXEL_OFF, 0, 0, AccessInst, 0);
00271     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_ON, 0, 0, AccessInst, 0);
00272     ILI9488_SpiSendCommand(ILI9488_CMD_NORMAL_DISP_MODE_ON, 0, 0, AccessInst, 0);
00273 }
00274 
00275 /**
00276  * \brief Turn off the ILI9488.
00277  */
00278 void ILI9488_SpiOff( void )
00279 {
00280     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_OFF, 0, 0, AccessInst, 0);
00281 }
00282 
00283 /**
00284  * \brief ILI9488 configure landscape.
00285  * \Param dwRGB RGB mode.
00286  * \Param LandscaprMode Landscape Mode.
00287  */
00288 void ILI9488_SpiSetDisplayLandscape( uint8_t dwRGB, uint8_t LandscapeMode )
00289 {
00290     uint8_t value;
00291     if(LandscapeMode) {
00292         if(dwRGB) {
00293             value = 0xE8;
00294         } else {
00295             value = 0xE0;
00296         }
00297     } else {
00298         if(dwRGB) {
00299             value = 0x48;
00300         } else {
00301             value = 0x40;
00302         }
00303     }
00304     ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_ACCESS_CONTROL, &value, 0, AccessWrite, sizeof(value));
00305 }
00306 
00307 #endif
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines