/* Display all possible 16-bit colors on the TFT with ILI9340 * * This program initialize the ILI9340 controller of a QVGA TFT * display then show all possible 16-bit colors. * * Built and tested with Keil MDK-ARM v5.24a and TM4C_DFP v1.1.0 */ #include "TM4C123.h" #define TFTWIDTH 240 #define TFTHEIGHT 320 #define ILI9340_SLPOUT 0x11 #define ILI9340_GAMMASET 0x26 #define ILI9340_DISPON 0x29 #define ILI9340_CASET 0x2A #define ILI9340_PASET 0x2B #define ILI9340_RAMWR 0x2C #define ILI9340_MADCTL 0x36 #define ILI9340_MADCTL_MX 0x40 #define ILI9340_MADCTL_BGR 0x08 #define ILI9340_PIXFMT 0x3A #define ILI9340_FRMCTR1 0xB1 #define ILI9340_DFUNCTR 0xB6 #define ILI9340_PWCTR1 0xC0 #define ILI9340_PWCTR2 0xC1 #define ILI9340_VMCTR1 0xC5 #define ILI9340_VMCTR2 0xC7 #define ILI9340_GMCTRP1 0xE0 #define ILI9340_GMCTRN1 0xE1 #define ILI9340_setCommand() GPIOE->DATA &= ~(1 << 0); /* make DC PE0 low */ #define ILI9340_setData() GPIOE->DATA |= 1 << 0; /* make DC PE0 high */ #define ILI9340_assertSS() GPIOC->DATA &= ~(1 << 6); /* assert /SS */ #define ILI9340_deassertSS() GPIOC->DATA |= 1 << 6; /* deassert /SS */ #define ILI9340_reset() GPIOF->DATA &= ~(1 << 3); /* make RESET PF3 low */ #define ILI9340_dereset() GPIOF->DATA |= 1 << 3; /* make RESET PF3 high */ void SPI_init(void); void SPI_write(unsigned char data); void ILI9340_hardReset(void); void ILI9340_command(uint8_t command); void ILI9340_data(uint8_t data); void ILI9340_blockData(int32_t n, uint16_t color); void delayMs(int32_t n); void ILI9340_setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); void ILI9340_init(void); // define block size #define W 10 #define H 10 int32_t main(void) { uint32_t i, j; uint16_t color; ILI9340_init(); while(1) { for (i = 0; i < TFTHEIGHT / H; i++) { for (j = 0; j < TFTWIDTH / W; j++) { ILI9340_setWindow(j * W, i * H, j * W + W - 1, i * H + H - 1); ILI9340_blockData(W * H, color++); } } } } // Initialize SPI for TFT controller void SPI_init(void) { SYSCTL->RCGCSSI |= 0x04; // enable clock to SSI2 SYSCTL->RCGCGPIO |= 0x02; // enable clock to GPIOB SYSCTL->RCGCGPIO |= 0x04; // enable clock to GPIOC SYSCTL->RCGCGPIO |= 0x10; // enable clock to GPIOE SYSCTL->RCGCGPIO |= 0x20; // enable clock to GPIOF // PORTB 7, 4 for SSI2 TX and SCLK GPIOB->AMSEL &= ~0x90; // turn off analog of PORTB 7, 4 GPIOB->AFSEL |= 0x90; // PORTB 7, 4 for alternate function GPIOB->PCTL &= ~0xF00F0000; // clear functions for PORTB 7, 4 GPIOB->PCTL |= 0x20020000; // PORTB 7, 4 for SSI2 function GPIOB->DEN |= 0x90; // PORTB 7, 4 as digital pins // PORTC 6 for SSI2 slave select GPIOC->AMSEL &= ~(1 << 6); // disable analog GPIOC->DIR |= 1 << 6; // set PORTC 6 as output for CS GPIOC->DEN |= 1 << 6; // set PORTC 6 as digital pins GPIOC->DATA |= 1 << 6; // set PORTC 6 idle high // PORTF 3 for RESET GPIOF->AMSEL &= ~(1 << 3); // disable analog GPIOF->DIR |= 1 << 3; // set PORTF 3 as output for CS GPIOF->DEN |= 1 << 3; // set PORTF 3 as digital pins GPIOF->DATA |= 1 << 3; // set PORTF 3 idle high // PORTE 0 for DC select GPIOE->AMSEL &= ~(1 << 0); // disable analog GPIOE->DIR |= 1 << 0; // set PORTE 0 as output for CS GPIOE->DEN |= 1 << 0; // set PORTE 0 as digital pins GPIOE->DATA |= 1 << 0; // set PORTE 0 idle high SSI2->CR1 = 0; // make it master SSI2->CC = 0; // use system clock SSI2->CPSR = 5; // clock prescaler divide by 5 gets 10 MHz clock SSI2->CR0 = 0x0007; // clock rate div by 1, phase/polarity 0 0, mode freescale, data size 8 SSI2->CR1 = 2; // enable SSI2 } // write data to SPI void SPI_write(unsigned char data) { SSI2->DR = data; // write data while (SSI2->SR & 0x10) ; // wait for transmit done } // hardware reset of TFT controller void ILI9340_hardReset(void) { delayMs(2000); ILI9340_reset(); delayMs(1); ILI9340_dereset(); delayMs(2000); } // send a command to TFT controller void ILI9340_command(uint8_t command) { ILI9340_setCommand(); ILI9340_assertSS(); SPI_write(command); ILI9340_deassertSS(); } // send a data to TFT controller void ILI9340_data(uint8_t data) { ILI9340_setData(); ILI9340_assertSS(); SPI_write(data); ILI9340_deassertSS(); } // send a block of data to TFT controller void ILI9340_blockData(int32_t n, uint16_t color) { ILI9340_setData(); ILI9340_assertSS(); while (n--) { SPI_write(color >> 8); SPI_write(color & 0xFF); } ILI9340_deassertSS(); } // set a window in the display to receive data void ILI9340_setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { ILI9340_command(ILI9340_CASET); // Column addr set ILI9340_data(x0 >> 8); // XSTART ILI9340_data(x0 & 0xFF); ILI9340_data(x1 >> 8); // XEND ILI9340_data(x1 & 0xFF); ILI9340_command(ILI9340_PASET); // Row addr set ILI9340_data(y0>>8); // YSTART ILI9340_data(y0); ILI9340_data(y1>>8); // YEND ILI9340_data(y1); ILI9340_command(ILI9340_RAMWR); // write to RAM } // initialize the TFT controller void ILI9340_init(void) { SPI_init(); ILI9340_hardReset(); ILI9340_command(0xEF); ILI9340_data(0x03); ILI9340_data(0x80); ILI9340_data(0x02); ILI9340_command(0xCF); ILI9340_data(0x00); ILI9340_data(0xC1); ILI9340_data(0x30); ILI9340_command(0xED); ILI9340_data(0x64); ILI9340_data(0x03); ILI9340_data(0x12); ILI9340_data(0x81); ILI9340_command(0xE8); ILI9340_data(0x85); ILI9340_data(0x00); ILI9340_data(0x78); ILI9340_command(0xCB); ILI9340_data(0x39); ILI9340_data(0x2C); ILI9340_data(0x00); ILI9340_data(0x34); ILI9340_data(0x02); ILI9340_command(0xF7); ILI9340_data(0x20); ILI9340_command(0xEA); ILI9340_data(0x00); ILI9340_data(0x00); ILI9340_command(ILI9340_PWCTR1); //Power control ILI9340_data(0x23); //VRH[5:0] ILI9340_command(ILI9340_PWCTR2); //Power control ILI9340_data(0x10); //SAP[2:0];BT[3:0] ILI9340_command(ILI9340_VMCTR1); //VCM control ILI9340_data(0x3e); ILI9340_data(0x28); ILI9340_command(ILI9340_VMCTR2); //VCM control2 ILI9340_data(0x86); ILI9340_command(ILI9340_MADCTL); // Memory Access Control ILI9340_data(ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR); ILI9340_command(ILI9340_PIXFMT); ILI9340_data(0x55); ILI9340_command(ILI9340_FRMCTR1); ILI9340_data(0x00); ILI9340_data(0x18); ILI9340_command(ILI9340_DFUNCTR); // Display Function Control ILI9340_data(0x08); ILI9340_data(0x82); ILI9340_data(0x27); ILI9340_command(0xF2); // 3Gamma Function Disable ILI9340_data(0x00); ILI9340_command(ILI9340_GAMMASET); //Gamma curve selected ILI9340_data(0x01); ILI9340_command(ILI9340_GMCTRP1); //Set Gamma ILI9340_data(0x0F); ILI9340_data(0x31); ILI9340_data(0x2B); ILI9340_data(0x0C); ILI9340_data(0x0E); ILI9340_data(0x08); ILI9340_data(0x4E); ILI9340_data(0xF1); ILI9340_data(0x37); ILI9340_data(0x07); ILI9340_data(0x10); ILI9340_data(0x03); ILI9340_data(0x0E); ILI9340_data(0x09); ILI9340_data(0x00); ILI9340_command(ILI9340_GMCTRN1); //Set Gamma ILI9340_data(0x00); ILI9340_data(0x0E); ILI9340_data(0x14); ILI9340_data(0x03); ILI9340_data(0x11); ILI9340_data(0x07); ILI9340_data(0x31); ILI9340_data(0xC1); ILI9340_data(0x48); ILI9340_data(0x08); ILI9340_data(0x0F); ILI9340_data(0x0C); ILI9340_data(0x31); ILI9340_data(0x36); ILI9340_data(0x0F); ILI9340_command(ILI9340_SLPOUT); //Exit Sleep delayMs(120); ILI9340_command(ILI9340_DISPON); //Display on } // The CPU core clock is set to 50 MHz in SystemInit(). void delayMs(int32_t n) { int32_t i; int32_t j; for(i = 0 ; i < n; i++) for (j = 0; j < 9937; j++) {} }