/* * File: ILI9341.c * Author: MikroTronik * * Created on January 24, 2020, 3:27 PM */ /* * File: ILI9341.c * Author: MikroTronik * * Created on January 18, 2020, 2:08 PM */ #include #include #include #include #include #include "mcc_generated_files/mcc.h" #include "mcc_generated_files/pin_manager.h" #include "mcc_generated_files/spi2.h" #include "ILI9341.h" #include "Graphics.h" #include "delay.h" uint16_t _width, ///< Display width as modified by current rotation _height; ///< Display height as modified by current rotation uint8_t rotation; ///< Display rotation (0 thru 3) const uint8_t initcmd1[] = { 0xEF, 3, 0x03, 0x80, 0x02, 0xCF, 3, 0x00, 0xC1, 0x30, 0xED, 4, 0x64, 0x03, 0x12, 0x81, 0xE8, 3, 0x85, 0x00, 0x78, 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, 0xF7, 1, 0x20, 0xEA, 2, 0x00, 0x00, ILI9341_PWCTR1, 1, 0x23, // Power control VRH[5:0] ILI9341_PWCTR2, 1, 0x10, // Power control SAP[2:0];BT[3:0] ILI9341_VMCTR1, 2, 0x3e, 0x28, // VCM control ILI9341_VMCTR2, 1, 0x86, // VCM control2 ILI9341_MADCTL, 1, 0x48, // Memory Access Control ILI9341_VSCRSADD, 1, 0x00, // Vertical scroll zero ILI9341_PIXFMT, 1, 0x55, ILI9341_FRMCTR1, 2, 0x00, 0x18, ILI9341_DFUNCTR, 3, 0x08, 0x82, 0x27, // Display Function Control 0xF2, 1, 0x00, // 3Gamma Function Disable ILI9341_GAMMASET, 1, 0x01, // Gamma curve selected ILI9341_GMCTRP1, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, // Set Gamma 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, ILI9341_GMCTRN1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, // Set Gamma 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, ILI9341_SLPOUT, 0x80, // Exit Sleep ILI9341_DISPON, 0x80, // Display on 0x00 // End of list }; void startWrite(void) { TFT_CS = 0; } void endWrite(void) { TFT_CS = 1; } void writeCommand(uint8_t cmd) { TFT_DC = 0; SPI2_Exchange8bit(cmd); TFT_DC = 1; } void tft_begin(void) { #ifdef TFT_RST TFT_RST = 1; TRIS_RES = 0; _delay_ms(100); TFT_RST = 0; _delay_ms(100); TFT_RST = 1; _delay_ms(200); #else // If no hardware reset pin... writeCommand(ILI9341_SWRESET); // Engage software reset #endif TFT_CS = 1; TRIS_CS = 0; TRIS_DC = 0; startWrite(); uint8_t cmd, x, numArgs; const uint8_t *addr = initcmd1; cmd = *addr++; while (cmd > 0) { writeCommand(cmd); x = *addr++; numArgs = x & 0x7F; while (numArgs--) SPI2_Exchange8bit(*addr++); if (x & 0x80) _delay_ms(150); cmd = *addr++; } endWrite(); _width = ILI9341_TFTWIDTH; _height = ILI9341_TFTHEIGHT; rotation = 0; } void fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) { if (w && h) { // Nonzero width and height? uint8_t hi = color >> 8, lo = color; if ((x >= _width) || (y >= _height)) return; if ((x + w - 1) >= _width) w = _width - x; if ((y + h - 1) >= _height) h = _height - y; startWrite(); setAddrWindow(x, y, w, h); uint32_t px = (uint32_t) w * h; while (px--) { SPI2_Exchange8bit(hi); SPI2_Exchange8bit(lo); } endWrite(); } } void setAddrWindow(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h) { uint16_t x2 = (x1 + w - 1), y2 = (y1 + h - 1); writeCommand(ILI9341_CASET); // Column address set SPI2_Exchange8bit(x1 >> 8); SPI2_Exchange8bit(x1); SPI2_Exchange8bit(x2 >> 8); SPI2_Exchange8bit(x2); writeCommand(ILI9341_PASET); // Row address set SPI2_Exchange8bit(y1 >> 8); SPI2_Exchange8bit(y1); SPI2_Exchange8bit(y2 >> 8); SPI2_Exchange8bit(y2); writeCommand(ILI9341_RAMWR); // Write to RAM } void fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } void setRotation(uint8_t m) { // printf("%s\r\n",__func__); rotation = m % 4; // can't be higher than 3 switch (rotation) { case 0: m = (MADCTL_MX | MADCTL_BGR); _width = ILI9341_TFTWIDTH; _height = ILI9341_TFTHEIGHT; break; case 1: m = (MADCTL_MV | MADCTL_BGR); _width = ILI9341_TFTHEIGHT; _height = ILI9341_TFTWIDTH; break; case 2: m = (MADCTL_MY | MADCTL_BGR); _width = ILI9341_TFTWIDTH; _height = ILI9341_TFTHEIGHT; break; case 3: m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR); _width = ILI9341_TFTHEIGHT; _height = ILI9341_TFTWIDTH; break; } startWrite(); writeCommand(ILI9341_MADCTL); SPI2_Exchange8bit(m); endWrite(); } void drawPixel(uint16_t x, uint16_t y, uint16_t color) { if ((x < _width) && (y < _height)) { startWrite(); setAddrWindow(x, y, 1, 1); SPI2_Exchange8bit(color >> 8); SPI2_Exchange8bit(color & 0xFF); // endWrite(); } } void drawHLine(uint16_t x, uint16_t y, uint16_t w, uint16_t color) { if ((x < _width) && (y < _height) && w) { uint8_t hi = color >> 8, lo = color; if ((x + w - 1) >= _width) w = _width - x; startWrite(); setAddrWindow(x, y, w, 1); while (w--) { SPI2_Exchange8bit(hi); SPI2_Exchange8bit(lo); } endWrite(); } } void drawVLine(uint16_t x, uint16_t y, uint16_t h, uint16_t color) { if ((x < _width) && (y < _height) && h) { uint8_t hi = color >> 8, lo = color; if ((y + h - 1) >= _height) h = _height - y; startWrite(); setAddrWindow(x, y, 1, h); while (h--) { SPI2_Exchange8bit(hi); SPI2_Exchange8bit(lo); } endWrite(); } } void invertDisplay(bool i) { startWrite(); writeCommand(i ? ILI9341_INVON : ILI9341_INVOFF); endWrite(); } void tft_scrollTo(uint16_t y) { startWrite(); writeCommand(ILI9341_VSCRSADD); SPI2_Exchange8bit(y >> 8); SPI2_Exchange8bit(y); endWrite(); } uint8_t tft_readcommand8(uint8_t command, uint8_t index) { startWrite(); writeCommand(0xD9); // woo sekret command? SPI2_Exchange8bit(0x10 + index); writeCommand(command); uint8_t r = SPI2_Exchange8bit(0xFF); endWrite(); return r; } uint16_t pushColor(uint16_t color) { uint8_t hi = color >> 8, lo = color; startWrite(); SPI2_Exchange8bit(hi); SPI2_Exchange8bit(lo); endWrite(); } void DrawText(uint8_t x, uint8_t y, char *_text, uint8_t size, uint16_t color) { display_setTextColor1(color); display_setCursor(x, y); display_setTextSize(size); while (*_text != 0) display_print(*_text++); }