Questions? Call us: +1 760-918-6722

Example 4-bit SPI initialization code for Arduino

Hi folks, There are a few threads here where folks are noting that they're having difficulty communicating over SPI to the DT028ATFT. In one post, someone even notes that "The factory has hard-wired the ILI9341 into 3-wire 9-bit mode on the FPC", which nearly made me very unhappy as this isn't noted in the datasheet, and I'd already had boards fabbed using the "4-wire 8-bit Serial Interface II" (IM[3:0] = 1110). I've had luck initializing the display using 4-bit mode and sending a line demo over SPI, so I thought I'd post this clunky test code to for the Arduino Due here incase it's useful. The backlight isn't under software control in this example, so you'll have to enable it somewhere along the way in your own code or application. Note that some of this test code was taken from the Adafruit Graphics and ILI9341 libraries, as well as code folks have posted on this forum. best wishes -----


#include "ili9341.h"
const int LCD_CS = 50;
const int LCD_WR = 51;
const int LCD_RESET = 52;
const int SPI_MISO = 74;
const int SPI_MOSI = 75;
const int SPI_CLK = 76;
#define _height 200
#define _width 320
void lcd_pin_setup() {
// LCD Pin configuration
pinMode(LCD_CS, OUTPUT);
pinMode(LCD_WR, OUTPUT);
pinMode(LCD_RESET, OUTPUT);
digitalWrite(LCD_RESET, HIGH);
digitalWrite(LCD_CS, HIGH);
digitalWrite(LCD_WR, HIGH);
}
void lcd_reset() {
// Reset LCD display
digitalWrite(LCD_RESET, HIGH);
delay(200);
digitalWrite(LCD_RESET, LOW);
delay(200);
digitalWrite(LCD_RESET, HIGH);
delay(200);
}
void spi_init() {
pinMode(SPI_MISO, INPUT);
pinMode(SPI_MOSI, OUTPUT);
pinMode(SPI_CLK, OUTPUT);
}
void spi_writebyte(uint8_t c) {
for(uint8_t bit = 0x80; bit; bit >>= 1) {
if(c & bit) {
digitalWrite(SPI_MOSI, HIGH);
} else {
digitalWrite(SPI_MOSI, LOW);
}
digitalWrite(SPI_CLK, HIGH);
digitalWrite(SPI_CLK, LOW);
}
}
void writecommand(uint8_t c) {
writecommand_8bit(c);
}
void writedata(uint8_t c) {
writedata_8bit(c);
}
void writedata16(uint8_t c1, uint8_t c2) {
digitalWrite(LCD_WR, HIGH); // 1 signifies data
digitalWrite(LCD_CS, LOW);
spi_writebyte(c1);
spi_writebyte(c2);
delayMicroseconds(10);
digitalWrite(LCD_CS, HIGH);
}
void writecommand_8bit(uint8_t c) {
digitalWrite(LCD_WR, LOW); // 0 signifies command
digitalWrite(LCD_CS, LOW);
// Write data byte
spi_writebyte(c);
delayMicroseconds(10);
digitalWrite(LCD_CS, HIGH);
}
void writedata_8bit(uint8_t c) {
digitalWrite(LCD_WR, HIGH); // 1 signifies data
digitalWrite(LCD_CS, LOW);
// Write data byte
spi_writebyte(c);
delayMicroseconds(10);
digitalWrite(LCD_CS, HIGH);
}
void lcd_init() {
writecommand(0xEF);
writedata(0x03);
writedata(0x80);
writedata(0x02);
writecommand(0xCF);
writedata(0x00);
writedata(0XC1);
writedata(0X30);
writecommand(0xED);
writedata(0x64);
writedata(0x03);
writedata(0X12);
writedata(0X81);
writecommand(0xE8);
writedata(0x85);
writedata(0x00);
writedata(0x78);
writecommand(0xCB);
writedata(0x39);
writedata(0x2C);
writedata(0x00);
writedata(0x34);
writedata(0x02);
writecommand(0xF7);
writedata(0x20);
writecommand(0xEA);
writedata(0x00);
writedata(0x00);
writecommand(ILI9341_PWCTR1); //Power control
writedata(0x23); //VRH[5:0]
writecommand(ILI9341_PWCTR2); //Power control
writedata(0x10); //SAP[2:0];BT[3:0]
writecommand(ILI9341_VMCTR1); //VCM control
writedata(0x3e); //
writedata(0x28);
writecommand(ILI9341_VMCTR2); //VCM control2
writedata(0x86); //--
writecommand(ILI9341_MADCTL); // Memory Access Control
writedata(0x48);
writecommand(ILI9341_PIXFMT);
writedata(0x55);
writecommand(ILI9341_FRMCTR1);
writedata(0x00);
writedata(0x18);
writecommand(ILI9341_DFUNCTR); // Display Function Control
writedata(0x08);
writedata(0x82);
writedata(0x27);
writecommand(0xF2); // 3Gamma Function Disable
writedata(0x00);
writecommand(ILI9341_GAMMASET); //Gamma curve selected
writedata(0x01);
writecommand(ILI9341_GMCTRP1); //Set Gamma
writedata(0x0F);
writedata(0x31);
writedata(0x2B);
writedata(0x0C);
writedata(0x0E);
writedata(0x08);
writedata(0x4E);
writedata(0xF1);
writedata(0x37);
writedata(0x07);
writedata(0x10);
writedata(0x03);
writedata(0x0E);
writedata(0x09);
writedata(0x00);
writecommand(ILI9341_GMCTRN1); //Set Gamma
writedata(0x00);
writedata(0x0E);
writedata(0x14);
writedata(0x03);
writedata(0x11);
writedata(0x07);
writedata(0x31);
writedata(0xC1);
writedata(0x48);
writedata(0x08);
writedata(0x0F);
writedata(0x0C);
writedata(0x31);
writedata(0x36);
writedata(0x0F);
writecommand(ILI9341_SLPOUT); //Exit Sleep
delay(120);
writecommand(ILI9341_DISPON); //Display on
}
void lcd_init_rgb() {
//Software Reset
writecommand(0x01);
delay(200);
//RGB
writecommand(0xB0);
writedata(0xC0);
//Interface control
writecommand(0xF6);
writedata(0x01);
writedata(0x01);
writedata(0x06);
//Pixel format
writecommand(0x3A);
writedata(0x56);
// Memory Access Control
writecommand(0x36);
writedata(0x48); // Row-Col Exch, BGR color direction
// Sleep Out
writecommand(0x11);
delay(200);
//Display On
writecommand(0x29);
}
void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
writecommand(ILI9341_CASET); // Column addr set
writedata(x0 >> 8);
writedata(x0 & 0xFF); // XSTART
writedata(x1 >> 8);
writedata(x1 & 0xFF); // XEND
writecommand(ILI9341_PASET); // Row addr set
writedata(y0>>8);
writedata(y0); // YSTART
writedata(y1>>8);
writedata(y1); // YEND
writecommand(ILI9341_RAMWR); // write to RAM
}
void drawPixel(int16_t x, int16_t y, uint16_t color) {
if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return;
setAddrWindow(x,y,x+1,y+1);
writedata16(color >> 8, color);
}
unsigned long testLines(uint16_t color) {
unsigned long start, t;
int x1, y1, x2, y2,
w = _width,
h = _height;
// tft.fillScreen(ILI9341_BLACK);
x1 = y1 = 0;
y2 = h - 1;
start = micros();
for(x2=0; x2 x2 = w - 1;
for(y2=0; y2 t = micros() - start; // fillScreen doesn't count against timing
// tft.fillScreen(ILI9341_BLACK);
x1 = w - 1;
y1 = 0;
y2 = h - 1;
start = micros();
for(x2=0; x2 x2 = 0;
for(y2=0; y2 t += micros() - start;
// tft.fillScreen(ILI9341_BLACK);
x1 = 0;
y1 = h - 1;
y2 = 0;
start = micros();
for(x2=0; x2 x2 = w - 1;
for(y2=0; y2 t += micros() - start;
// tft.fillScreen(ILI9341_BLACK);
x1 = w - 1;
y1 = h - 1;
y2 = 0;
start = micros();
for(x2=0; x2 x2 = 0;
for(y2=0; y2
return micros() - start;
}
#define swap(a, b) { int16_t t = a; a = b; b = t; }
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
int16_t steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
swap(x0, y0);
swap(x1, y1);
}
if (x0 > x1) {
swap(x0, x1);
swap(y0, y1);
}
int16_t dx, dy;
dx = x1 - x0;
dy = abs(y1 - y0);
int16_t err = dx / 2;
int16_t ystep;
if (y0 < y1) {
ystep = 1;
} else {
ystep = -1;
}
for (; x0<=x1; x0++) {
if (steep) {
drawPixel(y0, x0, color);
} else {
drawPixel(x0, y0, color);
}
err -= dy;
if (err < 0) {
y0 += ystep;
err += dx;
}
}
}
void setup() {
// put your setup code here, to run once:
delay(1000);
lcd_pin_setup();
lcd_reset();
// Initialize serial console...
Serial.begin(9600);
Serial.println("Initializing... ");
spi_init();
Serial.println("lcd_init()... ");
lcd_init();
delay(500);
Serial.println("testLines... ");
testLines(ILI9341_CYAN);
delay(500);
/*
Serial.println ("lcd_init_rgb()...");
delay(500);
lcd_init_rgb();
*/
Serial.println("Done... ");
}
void loop() {
// put your main code here, to run repeatedly:
}
-------------------
// ili9341.h
#define ILI9341_TFTWIDTH 240
#define ILI9341_TFTHEIGHT 320
#define ILI9341_NOP 0x00
#define ILI9341_SWRESET 0x01
#define ILI9341_RDDID 0x04
#define ILI9341_RDDST 0x09
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_RDMODE 0x0A
#define ILI9341_RDMADCTL 0x0B
#define ILI9341_RDPIXFMT 0x0C
#define ILI9341_RDIMGFMT 0x0A
#define ILI9341_RDSELFDIAG 0x0F
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#define ILI9341_CASET 0x2A
#define ILI9341_PASET 0x2B
#define ILI9341_RAMWR 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PTLAR 0x30
#define ILI9341_MADCTL 0x36
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_RDID1 0xDA
#define ILI9341_RDID2 0xDB
#define ILI9341_RDID3 0xDC
#define ILI9341_RDID4 0xDD
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
/*
#define ILI9341_PWCTR6 0xFC
*/
// Color definitions
#define ILI9341_BLACK 0x0000
#define ILI9341_BLUE 0x001F
#define ILI9341_RED 0xF800
#define ILI9341_GREEN 0x07E0
#define ILI9341_CYAN 0x07FF
#define ILI9341_MAGENTA 0xF81F
#define ILI9341_YELLOW 0xFFE0
#define ILI9341_WHITE 0xFFFF