SAMV71 Xplained Ultra Software Package 1.5

ili9488_spi.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
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 
00113     for (i = 3; i > 0; i--) {
00114 
00115         ILI9488_SpiSendCommand(ILI9488_CMD_SPI_READ_SETTINGS, &reg, 0, AccessWrite, 1);
00116         reg++;
00117         ILI9488_SpiSendCommand(ILI9488_CMD_READ_ID4, 0, 0, AccessInst, 0);
00118         ILI9488_SpiSendCommand(0, 0, chipidBuf, AccessRead, 2);
00119         chipid |= (chipidBuf[1] & 0xFF) << ((i - 1) << 3);
00120         ILI9488_SpiSendCommand(ILI9488_CMD_SPI_READ_SETTINGS, &param, 0, AccessWrite,
00121                                1);
00122     }
00123 
00124     return chipid;
00125 }
00126 
00127 /**
00128  * \brief Set ILI9488 Pixel Format in SPI/SMC mode.
00129  * \param format Format of pixel
00130  */
00131 void ILI9488_SpiSetPixelFormat(uint8_t format)
00132 {
00133     ILI9488_SpiSendCommand(ILI9488_CMD_COLMOD_PIXEL_FORMAT_SET, &format, 0,
00134                            AccessWrite, 1);
00135 }
00136 
00137 /**
00138  * \brief Initialize the ILI9488 controller in SPI/SMC mode.
00139  */
00140 uint32_t ILI9488_SpiInitialize(sXdmad *dmad)
00141 {
00142     uint32_t chipid = 0;
00143     uint8_t param;
00144 
00145     _ILI9488_Spi_HW_Initialize();
00146     ILI9488_SpiInitializeWithDma(dmad);
00147 
00148     ILI9488_SpiSendCommand(ILI9488_CMD_SOFTWARE_RESET, 0, 0, AccessInst, 0);
00149     Wait(200);
00150 
00151     ILI9488_SpiSendCommand(ILI9488_CMD_SLEEP_OUT, 0, 0, AccessInst, 0);
00152     Wait(200);
00153 
00154     // make it tRGB and reverse the column order
00155     param = 0x48;
00156     ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_ACCESS_CONTROL, &param, 0,
00157                            AccessWrite, 1);
00158     Wait(100);
00159 
00160     param = 0x04;
00161     ILI9488_SpiSendCommand(ILI9488_CMD_CABC_CONTROL_9, &param, 0, AccessWrite, 1);
00162 
00163     if ((chipid = ILI9488_SpiReadChipId()) != ILI9488_DEVICE_CODE) {
00164         printf("Read ILI9488 chip ID (0x%04x) error, skip initialization.\r\n",
00165                 (unsigned int)chipid);
00166         return 1;
00167     }
00168 
00169     ILI9488_SpiSetPixelFormat(6);
00170     ILI9488_SpiSendCommand(ILI9488_CMD_NORMAL_DISP_MODE_ON, 0, 0, AccessInst, 0);
00171     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_ON, 0, 0, AccessInst, 0);
00172     return 0;
00173 }
00174 
00175 /**
00176  * \brief ILI9488 configure cursor in SPI/SMC mode.
00177  * \Param x X position.
00178  * \Param y Y position.
00179  */
00180 void ILI9488_SpiSetCursor(uint16_t x, uint16_t y)
00181 {
00182     /* Set Horizontal Address Start Position */
00183     uint32_t cnt = 0;
00184 
00185     uint8_t buf[4];
00186     cnt = sizeof(buf);
00187     buf[0] = get_8b_to_16b(x);
00188     buf[1] = get_0b_to_8b(x);
00189     x += 1;
00190     buf[2] = get_8b_to_16b(x);
00191     buf[3] = get_0b_to_8b(x);
00192     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t *)buf, 0,
00193                            AccessWrite, cnt);
00194     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00195 
00196     /* Set Horizontal Address End Position */
00197     buf[0] = get_8b_to_16b(y);
00198     buf[1] = get_0b_to_8b(y);
00199     y += 1;
00200     buf[2] = get_8b_to_16b(y);
00201     buf[3] = get_0b_to_8b(y);
00202     ILI9488_SpiSendCommand(ILI9488_CMD_PAGE_ADDRESS_SET, (uint8_t *)buf, 0,
00203                            AccessWrite, cnt);
00204     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00205 }
00206 
00207 /**
00208  * \brief ILI9488 configure window.
00209  * \Param dwX X start position.
00210  * \Param dwX Y start position.
00211  * \Param dwWidth  Width of window.
00212  * \Param dwHeight Height of window.
00213  */
00214 void ILI9488_SpiSetWindow(uint16_t dwX, uint16_t dwY, uint16_t dwWidth,
00215                            uint16_t dwHeight)
00216 {
00217     uint16_t ColStart, ColEnd, RowStart, RowEnd;
00218     uint32_t cnt = 0;
00219     uint8_t buf[4];
00220     cnt = sizeof(buf);
00221     ColStart  =  dwX;
00222     ColEnd    =  dwWidth + dwX;
00223 
00224     RowStart = dwY;
00225     RowEnd   = dwHeight + dwY;
00226 
00227     buf[0] = get_8b_to_16b(ColStart);
00228     buf[1] = get_0b_to_8b(ColStart);
00229     buf[2] = get_8b_to_16b(ColEnd);
00230     buf[3] = get_0b_to_8b(ColEnd);
00231     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t *)buf, 0,
00232                            AccessWrite, cnt);
00233     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00234 
00235     /* Set Horizontal Address End Position */
00236     buf[0] = get_8b_to_16b(RowStart);
00237     buf[1] = get_0b_to_8b(RowStart);
00238     buf[2] = get_8b_to_16b(RowEnd);
00239     buf[3] = get_0b_to_8b(RowEnd);
00240     ILI9488_SpiSendCommand(ILI9488_CMD_PAGE_ADDRESS_SET, (uint8_t *)buf, 0,
00241                            AccessWrite, cnt);
00242     ILI9488_SpiSendCommand(ILI9488_CMD_NOP, 0, 0, AccessInst, 0);
00243 }
00244 
00245 /**
00246  * \brief ILI9488 configure window with full size.
00247  */
00248 void ILI9488_SpiSetFullWindow(void)
00249 {
00250     uint16_t c_start, c_end, r_start, r_end;
00251     uint32_t cnt = 0;
00252     uint8_t buf[4];
00253     cnt = sizeof(buf);
00254     c_start =  0;
00255     c_end =  ILI9488_LCD_WIDTH - 1;
00256 
00257     r_start = 0;
00258     r_end   = ILI9488_LCD_HEIGHT - 1;
00259 
00260     /* Set Horizontal Address Start Position */
00261     buf[0] = get_8b_to_16b(c_start);
00262     buf[1] = get_0b_to_8b(c_start);
00263     buf[2] = get_8b_to_16b(c_end);
00264     buf[3] = get_0b_to_8b(c_end);
00265     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t *)buf, 0,
00266                            AccessWrite, cnt);
00267     ILI9488_SpiSendCommand(ILI9488_CMD_NOP , 0, 0, AccessInst, 0);
00268 
00269     /* Set Horizontal Address End Position */
00270     buf[0] = get_8b_to_16b(r_start);
00271     buf[1] = get_0b_to_8b(r_start);
00272     buf[2] = get_8b_to_16b(r_end);
00273     buf[3] = get_0b_to_8b(r_end);
00274     ILI9488_SpiSendCommand(ILI9488_CMD_COLUMN_ADDRESS_SET, (uint8_t *)buf, 0,
00275                            AccessWrite, cnt);
00276     ILI9488_SpiSendCommand(ILI9488_CMD_NOP , 0, 0, AccessInst, 0);
00277 }
00278 
00279 /**
00280  * \brief Turn on the ILI9488.
00281  */
00282 void ILI9488_SpiOn(void)
00283 {
00284     ILI9488_SpiSendCommand(ILI9488_CMD_PIXEL_OFF, 0, 0, AccessInst, 0);
00285     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_ON, 0, 0, AccessInst, 0);
00286     ILI9488_SpiSendCommand(ILI9488_CMD_NORMAL_DISP_MODE_ON, 0, 0, AccessInst, 0);
00287 }
00288 
00289 /**
00290  * \brief Turn off the ILI9488.
00291  */
00292 void ILI9488_SpiOff(void)
00293 {
00294     ILI9488_SpiSendCommand(ILI9488_CMD_DISPLAY_OFF, 0, 0, AccessInst, 0);
00295 }
00296 
00297 /**
00298  * \brief ILI9488 configure landscape.
00299  * \Param dwRGB RGB mode.
00300  * \Param LandscaprMode Landscape Mode.
00301  */
00302 void ILI9488_SpiSetDisplayLandscape(uint8_t dwRGB, uint8_t LandscapeMode)
00303 {
00304     uint8_t value;
00305 
00306     if (LandscapeMode) {
00307         if (dwRGB)
00308             value = 0xE8;
00309         else
00310             value = 0xE0;
00311     } else {
00312         if (dwRGB)
00313             value = 0x48;
00314         else
00315             value = 0x40;
00316     }
00317 
00318     ILI9488_SpiSendCommand(ILI9488_CMD_MEMORY_ACCESS_CONTROL, &value, 0,
00319                            AccessWrite, sizeof(value));
00320 }
00321 
00322 /**
00323  * \brief Send single command to ILI9488
00324  * \param cmd  command.
00325  */
00326 static void ILI9488_SendCmd(uint8_t cmd)
00327 {
00328     uint32_t i;
00329     PIO_Clear(&lcd_spi_cds_pin);
00330     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, cmd);
00331 
00332     for (i = 0; i < 0x18; i++);
00333 }
00334 
00335 /**
00336  * \brief Draw a pixel on LCD with given color, DMA not used
00337  * \param x  X-coordinate of pixel.
00338  * \param y  Y-coordinate of pixel.
00339  * \param color  Pixel color.
00340  */
00341 void ILI9488_SetPixelColor(uint32_t x, uint32_t y, uint32_t color)
00342 {
00343     uint32_t i;
00344 
00345     /* Set Horizontal Address Start Position */
00346     ILI9488_SendCmd(ILI9488_CMD_COLUMN_ADDRESS_SET);
00347     PIO_Set(&lcd_spi_cds_pin);
00348     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(x));
00349     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(x));
00350     x++;
00351     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(x));
00352     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(x));
00353 
00354     for (i = 0; i < 0x18; i++);
00355 
00356     ILI9488_SendCmd(ILI9488_CMD_NOP);
00357 
00358     /* Set Horizontal Address End Position */
00359     ILI9488_SendCmd(ILI9488_CMD_PAGE_ADDRESS_SET);
00360     PIO_Set(&lcd_spi_cds_pin);
00361     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(y));
00362     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(y));
00363     y++;
00364     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(y));
00365     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(y));
00366 
00367     for (i = 0; i < 0x18; i++);
00368 
00369     ILI9488_SendCmd(ILI9488_CMD_NOP);
00370 
00371     /* Set Color */
00372     ILI9488_SendCmd(ILI9488_CMD_MEMORY_WRITE);
00373     PIO_Set(&lcd_spi_cds_pin);
00374     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_16b_to_24b(color));
00375     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_8b_to_16b(color));
00376     SPI_Write(ILI9488_SPI, SMC_EBI_LCD_CS, get_0b_to_8b(color));
00377 
00378     for (i = 0; i < 0x18; i++);
00379 }
00380 
00381 #endif
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines