Dear All,
Many apologies if this is an awfully n00b question – I’ve only just started working with Arduinos and have come a cropper on my first project.
I am trying to communicate with a cheap ILI9431 board using SPI. I can communicate with it fine using the old SPI functions, but whenever I use the ones for the DUE board, I break it.
Below is an example of the problem. You can comment/uncomment the #defines for “FastSPI” and “FastDigital” to switch between the old and new functions.
It works fine with FastDigital defined or undefined, but will never work with the FastSPI (DUE functions) defined.
I’m guessing it’s a n00b mistake with pin set-ups or I’ve failed to see a delay requirement in the ILI9431 datasheet (though I’ve tried liberally scattering delays throughout my code trying dumb luck and ignorance as my guide :)).
If anyone has experience with DUE SPI and can offer some help, I’d be very grateful.
Many thanks.
/*
Arduino DUE attached to ILI9341 board (3.3v)
*/
// *******************************************************
// Comment/Uncomment to test DUE SPI and Fast digitalWrite
// *******************************************************
#define FastDigital
#define FastSPI
// *******************************************************
// Connection to TFT
#define TFT_CS 10
#define TFT_LED 9
#define TFT_DC 8
#define TFT_RST 7
#include <SPI.h>
// Try to get more speed than from original digitalWrite function
inline void digitalWrite2(int pin, boolean dat)
{
if(dat) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
else g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
delayMicroseconds(2); // found this minimum delay was needed for code to work
}
// Send command to TFT
void sendCMD(uint8_t index)
{
// Set DC for command
#ifdef FastDigital
digitalWrite2(TFT_DC,LOW);
#else
digitalWrite(TFT_DC,LOW);
#endif
// Send index
#ifdef FastSPI
SPI.transfer(TFT_CS, index);
#else
digitalWrite(TFT_CS, LOW);
SPI.transfer(index);
digitalWrite(TFT_CS, HIGH);
#endif
// Set DC back to data
#ifdef FastDigital
digitalWrite2(TFT_DC, HIGH);
#else
digitalWrite(TFT_DC, HIGH);
#endif
}
// Read TFT register & parameter
uint8_t readREG(uint8_t addr, uint8_t param)
{
uint8_t data=0;
sendCMD(0xD9);
#ifdef FastSPI
SPI.transfer(TFT_CS, 0x10+param);
#else
digitalWrite(TFT_CS, LOW);
SPI.transfer(0x10+param);
digitalWrite(TFT_CS, HIGH);
#endif
// Set DC for command
#ifdef FastDigital
digitalWrite2(TFT_DC,LOW);
#else
digitalWrite(TFT_DC,LOW);
#endif
// Transfer address and get data
#ifdef FastSPI
SPI.transfer(TFT_CS, addr, SPI_CONTINUE);
//delay(10); // tried adding delay here but doesn't help
data = SPI.transfer(TFT_CS, 0x00);
#else
digitalWrite(TFT_CS, LOW);
SPI.transfer(addr);
data = SPI.transfer(0x00);
digitalWrite(TFT_CS, HIGH);
#endif
// Set DC back to data
#ifdef FastDigital
digitalWrite2(TFT_DC, HIGH);
#else
digitalWrite(TFT_DC, HIGH);
#endif
return data;
}
// Attempt reading the TFT's version - tries 5 times in case
// communications were not stable to start
uint32_t readID(uint32_t expected)
{
uint32_t lastID;
for (uint32_t tries=0; tries<5; tries++){
// Get three byte value from register D3 which holds the ID
lastID = readREG(0xD3,1) << 16;
lastID = lastID | readREG(0xD3,2) << 8;
lastID = lastID | readREG(0xD3,3);
if (lastID==expected) return lastID;
}
return lastID;
}
void setup()
{
uint32_t myID;
// Print the mode selected from un/commening the defines
#ifdef FastSPI
Serial.println("Running with fast SPI");
#else
Serial.println("Running with slow SPI");
#endif
#ifdef FastDigital
Serial.println("Running with fast digitialWrite");
#else
Serial.println("Running with slow digitalWrite");
#endif
// Setup pin directions
pinMode(TFT_CS,OUTPUT);
pinMode(TFT_DC,OUTPUT);
pinMode(TFT_LED,OUTPUT);
pinMode(TFT_RST,OUTPUT);
pinMode(13,OUTPUT);
// Output default values
digitalWrite(TFT_DC,LOW);
digitalWrite(TFT_LED,HIGH);
digitalWrite(TFT_CS, HIGH);
// Reset TFT
digitalWrite(TFT_RST,LOW);
delay(100);
digitalWrite(TFT_RST,HIGH);
// Initialise SPI
#ifdef FastSPI
SPI.begin(TFT_CS);
SPI.setClockDivider(21); // 4Mhz, same as default "slow" SPI
#else
SPI.begin();
#endif
myID = readID(0x9341); // the ID we're expecting from ILI9341
if (myID != 0x9341) {
// Print error
Serial.println("************");
Serial.print("Wrong TFT ID: expected 0x9341 but found 0x");
Serial.println(myID,HEX);
Serial.println("************");
} else {
// Print success
Serial.print("Success! TFT ID = 0x");
Serial.println(myID,HEX);
}
}
// Just blink the LED to prove it is alive
void loop()
{
digitalWrite2(13, HIGH);
delay(500);
digitalWrite2(13, LOW);
delay(500);
}