#include "ILI9341_STM32_Driver.h" volatile uint16_t LCD_HEIGHT = ILI9341_SCREEN_HEIGHT; volatile uint16_t LCD_WIDTH = ILI9341_SCREEN_WIDTH; void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { /* Deselect when Tx Complete */ if(hspi == HSPI_INSTANCE) { HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); } } static void ILI9341_SPI_Tx(uint8_t data) { while(!__HAL_SPI_GET_FLAG(HSPI_INSTANCE, SPI_FLAG_TXE)); HAL_SPI_Transmit_DMA(HSPI_INSTANCE, &data, 1); //HAL_SPI_Transmit(HSPI_INSTANCE, &data, 1, 10); } static void ILI9341_SPI_TxBuffer(uint8_t *buffer, uint16_t len) { while(!__HAL_SPI_GET_FLAG(HSPI_INSTANCE, SPI_FLAG_TXE)); HAL_SPI_Transmit_DMA(HSPI_INSTANCE, buffer, len); //HAL_SPI_Transmit(HSPI_INSTANCE, buffer, len, 10); } void ILI9341_WriteCommand(uint8_t cmd) { HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_RESET); //command HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); //select ILI9341_SPI_Tx(cmd); //HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); //deselect } void ILI9341_WriteData(uint8_t data) { HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); //data HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); //select ILI9341_SPI_Tx(data); //HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); //deselect } void ILI9341_WriteBuffer(uint8_t *buffer, uint16_t len) { HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); //data HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); //select ILI9341_SPI_TxBuffer(buffer, len); //HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); //deselect } void ILI9341_SetAddress(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { uint8_t buffer[4]; buffer[0] = x1 >> 8; buffer[1] = x1; buffer[2] = x2 >> 8; buffer[3] = x2; ILI9341_WriteCommand(0x2A); ILI9341_WriteBuffer(buffer, sizeof(buffer)); buffer[0] = y1 >> 8; buffer[1] = y1; buffer[2] = y2 >> 8; buffer[3] = y2; ILI9341_WriteCommand(0x2B); ILI9341_WriteBuffer(buffer, sizeof(buffer)); ILI9341_WriteCommand(0x2C); } void ILI9341_Reset(void) { HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_RESET); //Disable HAL_Delay(10); HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); //Select HAL_Delay(10); HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_SET); //Enable HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); //Deselect } void ILI9341_Enable(void) { HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_SET); //Enable } void ILI9341_Init(void) { ILI9341_Enable(); ILI9341_Reset(); //SOFTWARE RESET ILI9341_WriteCommand(0x01); HAL_Delay(10); //POWER CONTROL A ILI9341_WriteCommand(0xCB); ILI9341_WriteData(0x39); ILI9341_WriteData(0x2C); ILI9341_WriteData(0x00); ILI9341_WriteData(0x34); ILI9341_WriteData(0x02); //POWER CONTROL B ILI9341_WriteCommand(0xCF); ILI9341_WriteData(0x00); ILI9341_WriteData(0xC1); ILI9341_WriteData(0x30); //DRIVER TIMING CONTROL A ILI9341_WriteCommand(0xE8); ILI9341_WriteData(0x85); ILI9341_WriteData(0x00); ILI9341_WriteData(0x78); //DRIVER TIMING CONTROL B ILI9341_WriteCommand(0xEA); ILI9341_WriteData(0x00); ILI9341_WriteData(0x00); //POWER ON SEQUENCE CONTROL ILI9341_WriteCommand(0xED); ILI9341_WriteData(0x64); ILI9341_WriteData(0x03); ILI9341_WriteData(0x12); ILI9341_WriteData(0x81); //PUMP RATIO CONTROL ILI9341_WriteCommand(0xF7); ILI9341_WriteData(0x20); //POWER CONTROL,VRH[5:0] ILI9341_WriteCommand(0xC0); ILI9341_WriteData(0x23); //POWER CONTROL,SAP[2:0];BT[3:0] ILI9341_WriteCommand(0xC1); ILI9341_WriteData(0x10); //VCM CONTROL ILI9341_WriteCommand(0xC5); ILI9341_WriteData(0x3E); ILI9341_WriteData(0x28); //VCM CONTROL 2 ILI9341_WriteCommand(0xC7); ILI9341_WriteData(0x86); //MEMORY ACCESS CONTROL ILI9341_WriteCommand(0x36); ILI9341_WriteData(0x48); //PIXEL FORMAT ILI9341_WriteCommand(0x3A); ILI9341_WriteData(0x55); //FRAME RATIO CONTROL, STANDARD RGB COLOR ILI9341_WriteCommand(0xB1); ILI9341_WriteData(0x00); ILI9341_WriteData(0x18); //DISPLAY FUNCTION CONTROL ILI9341_WriteCommand(0xB6); ILI9341_WriteData(0x08); ILI9341_WriteData(0x82); ILI9341_WriteData(0x27); //3GAMMA FUNCTION DISABLE ILI9341_WriteCommand(0xF2); ILI9341_WriteData(0x00); //GAMMA CURVE SELECTED ILI9341_WriteCommand(0x26); ILI9341_WriteData(0x01); //POSITIVE GAMMA CORRECTION ILI9341_WriteCommand(0xE0); ILI9341_WriteData(0x0F); ILI9341_WriteData(0x31); ILI9341_WriteData(0x2B); ILI9341_WriteData(0x0C); ILI9341_WriteData(0x0E); ILI9341_WriteData(0x08); ILI9341_WriteData(0x4E); ILI9341_WriteData(0xF1); ILI9341_WriteData(0x37); ILI9341_WriteData(0x07); ILI9341_WriteData(0x10); ILI9341_WriteData(0x03); ILI9341_WriteData(0x0E); ILI9341_WriteData(0x09); ILI9341_WriteData(0x00); //NEGATIVE GAMMA CORRECTION ILI9341_WriteCommand(0xE1); ILI9341_WriteData(0x00); ILI9341_WriteData(0x0E); ILI9341_WriteData(0x14); ILI9341_WriteData(0x03); ILI9341_WriteData(0x11); ILI9341_WriteData(0x07); ILI9341_WriteData(0x31); ILI9341_WriteData(0xC1); ILI9341_WriteData(0x48); ILI9341_WriteData(0x08); ILI9341_WriteData(0x0F); ILI9341_WriteData(0x0C); ILI9341_WriteData(0x31); ILI9341_WriteData(0x36); ILI9341_WriteData(0x0F); //EXIT SLEEP ILI9341_WriteCommand(0x11); HAL_Delay(100); //TURN ON DISPLAY ILI9341_WriteCommand(0x29); //STARTING ROTATION ILI9341_SetRotation(SCREEN_VERTICAL_1); } void ILI9341_SetRotation(uint8_t rotation) { ILI9341_WriteCommand(0x36); HAL_Delay(1); switch(rotation) { case SCREEN_VERTICAL_1: ILI9341_WriteData(0x40|0x08); LCD_WIDTH = 240; LCD_HEIGHT = 320; break; case SCREEN_HORIZONTAL_1: ILI9341_WriteData(0x20|0x08); LCD_WIDTH = 320; LCD_HEIGHT = 240; break; case SCREEN_VERTICAL_2: ILI9341_WriteData(0x80|0x08); LCD_WIDTH = 240; LCD_HEIGHT = 320; break; case SCREEN_HORIZONTAL_2: ILI9341_WriteData(0x40|0x80|0x20|0x08); LCD_WIDTH = 320; LCD_HEIGHT = 240; break; default: break; } } void ILI9341_DrawColor(uint16_t color) { uint8_t buffer[2] = {color>>8, color}; ILI9341_WriteBuffer(buffer, sizeof(buffer)); } void ILI9341_DrawColorBurst(uint16_t color, uint32_t size) { uint32_t BufferSize = 0; if((size*2) < BURST_MAX_SIZE) { BufferSize = size; } else { BufferSize = BURST_MAX_SIZE; } HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); uint8_t chifted = color>>8; uint8_t BurstBuffer[BufferSize]; for(uint32_t j = 0; j < BufferSize; j+=2) { BurstBuffer[j] = chifted; BurstBuffer[j+1] = color; } uint32_t SendingSize = size * 2; uint32_t SendingInBlock = SendingSize / BufferSize; uint32_t RemainderFromBlock = SendingSize % BufferSize; if(SendingInBlock != 0) { for(uint32_t j = 0; j < (SendingInBlock); j++) { HAL_SPI_Transmit(HSPI_INSTANCE, BurstBuffer, BufferSize, 10); } } HAL_SPI_Transmit(HSPI_INSTANCE, BurstBuffer, RemainderFromBlock, 10); HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); } void ILI9341_FillScreen(uint16_t color) { ILI9341_SetAddress(0, 0, LCD_WIDTH, LCD_HEIGHT); ILI9341_DrawColorBurst(color, LCD_WIDTH*LCD_HEIGHT); } void ILI9341_DrawPixel(uint16_t x,uint16_t y,uint16_t color) { if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return; uint8_t bufferX[4] = {x>>8, x, (x+1)>>8, (x+1)}; uint8_t bufferY[4] = {y>>8, y, (y+1)>>8, (y+1)}; uint8_t bufferC[2] = {color>>8, color}; ILI9341_WriteCommand(0x2A); //ADDRESS ILI9341_WriteBuffer(bufferX, sizeof(bufferX)); //XDATA ILI9341_WriteCommand(0x2B); //ADDRESS ILI9341_WriteBuffer(bufferY, sizeof(bufferY)); //YDATA ILI9341_WriteCommand(0x2C); //ADDRESS ILI9341_WriteBuffer(bufferC, sizeof(bufferC)); //COLOR } void ILI9341_DrawRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return; if((x+width-1)>=LCD_WIDTH) { width=LCD_WIDTH-x; } if((y+height-1)>=LCD_HEIGHT) { height=LCD_HEIGHT-y; } ILI9341_SetAddress(x, y, x+width-1, y+height-1); ILI9341_DrawColorBurst(color, height*width); } void ILI9341_DrawHLine(uint16_t x, uint16_t y, uint16_t width, uint16_t color) { if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return; if((x+width-1)>=LCD_WIDTH) { width=LCD_WIDTH-x; } ILI9341_SetAddress(x, y, x+width-1, y); ILI9341_DrawColorBurst(color, width); } void ILI9341_DrawVLine(uint16_t x, uint16_t y, uint16_t height, uint16_t color) { if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return; if((y+height-1)>=LCD_HEIGHT) { height=LCD_HEIGHT-y; } ILI9341_SetAddress(x, y, x, y+height-1); ILI9341_DrawColorBurst(color, height); }