Does the benchmark from above work?
Yes, I ran into this earlier when I was playing with refreshOnce.Hi all,
A single refreshOnce() call does the job, but a second call seems to throw an exception... I suppose (?)
Damn, debuging with only serial output is a real pain.
void ILI9341_t3DMA::stopRefresh(void) {
dmasettings[SCREEN_DMA_NUM_SETTINGS - 1].disableOnCompletion();
wait();
SPI.endTransaction();
[B]dmatx.disable();[/B]
autorefresh = 0;
[B] started = 0;[/B]
}
Yes, I ran into this earlier when I was playing with refreshOnce.
I had a fix for it that worked for me. (part of the earlier Pull request)
I updated:
I added the two bold lines.Code:void ILI9341_t3DMA::stopRefresh(void) { dmasettings[SCREEN_DMA_NUM_SETTINGS - 1].disableOnCompletion(); wait(); SPI.endTransaction(); [B]dmatx.disable();[/B] autorefresh = 0; [B] started = 0;[/B] }
Kurt
P.S. - Great stuff
This sounds very cool! Did I miss a note on Touch? >> To use Touch it would have to use an alternate SPI? Or on SAME SPI use the Interrupt detection code to stop and start the AUTO DMA updates and go SLOW MO normal during touch event. That should be easy to do right inside the TOUCH library code if there is an easy way to detect and disable/enable the AUTO refresh of the ILI9341. Probably take 5 minutes with those details. Would add a global and that 'detect' test on TOUCH Start (and wait for all clear on the display CS?) and global check on TOUCH Stop.
That's strange.
Thank you for that hint
void ILI9341_t3DMA::begin(void) {
ILI9341_t3::begin();
const uint32_t bytesPerLine = ILI9341_TFTWIDTH * 2;
const uint32_t maxLines = (65536 / bytesPerLine);
uint32_t i = 0, sum = 0, lines;
do {
//Source:
lines = min(maxLines, ILI9341_TFTHEIGHT - sum);
uint32_t len = lines * bytesPerLine;
dmasettings[i].TCD->SADDR = &screen[sum][0];
dmasettings[i].TCD->SOFF = 2;
dmasettings[i].TCD->ATTR_SRC = 1;
dmasettings[i].TCD->NBYTES = 2;
dmasettings[i].TCD->SLAST = -len;
dmasettings[i].TCD->BITER = len / 2;
dmasettings[i].TCD->CITER = len / 2;
//Destination:
dmasettings[i].TCD->DADDR = &SPI0_PUSHR;
dmasettings[i].TCD->DOFF = 0;
dmasettings[i].TCD->ATTR_DST = 1;
dmasettings[i].TCD->DLASTSGA = 0;
dmasettings[i].replaceSettingsOnCompletion(dmasettings[i + 1]);
sum += lines;
[COLOR="#0000CD"][B] //Interrupt
dmasettings[i].interruptAtCompletion();[/B][/COLOR]
} while (++i < SCREEN_DMA_NUM_SETTINGS);
dmasettings[SCREEN_DMA_NUM_SETTINGS - 1].replaceSettingsOnCompletion(dmasettings[0]);
dmatx.begin(false);
dmatx.triggerAtHardwareEvent(DMAMUX_SOURCE_SPI0_TX );
dmatx = dmasettings[0];
dmatx.attachInterrupt(dmaInterrupt);
[COLOR="#0000CD"][B] //dmasettings[SCREEN_DMA_NUM_SETTINGS - 1].interruptAtCompletion();[/B][/COLOR]
dfillScreen(0);
};
void setup() {
tft.begin();
//START DMA MODE
//tft.refresh();
Serial.begin(9600);
while (!Serial) ; // wait for Arduino Serial Monitor
Serial.println("ILI9341 Test!");
Serial.println(F("Benchmark Time (microseconds)"));
Serial.print(F("Screen fill "));
Serial.println(testFillScreen());
tft.refreshOnce();delay(200);
Serial.print(F("Text "));
Serial.println(testText());
tft.refreshOnce();delay(600);
Serial.print(F("Lines "));
Serial.println(testLines(ILI9341_CYAN));
tft.refreshOnce();delay(200);
Serial.print(F("Horiz/Vert Lines "));
Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
tft.refreshOnce();delay(200);
Serial.print(F("Rectangles (outline) "));
Serial.println(testRects(ILI9341_GREEN));
tft.refreshOnce();delay(200);
Serial.print(F("Rectangles (filled) "));
Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
tft.refreshOnce();delay(200);
Serial.print(F("Circles (filled) "));
Serial.println(testFilledCircles(10, ILI9341_MAGENTA));
Serial.print(F("Circles (outline) "));
Serial.println(testCircles(10, ILI9341_WHITE));
tft.refreshOnce();delay(200);
Serial.print(F("Triangles (outline) "));
Serial.println(testTriangles());
tft.refreshOnce();delay(200);
Serial.print(F("Triangles (filled) "));
Serial.println(testFilledTriangles());
tft.refreshOnce();delay(200);
Serial.print(F("Rounded rects (outline) "));
Serial.println(testRoundRects());
tft.refreshOnce();delay(200);
Serial.print(F("Rounded rects (filled) "));
Serial.println(testFilledRoundRects());
tft.refreshOnce();delay(200);
Serial.println(F("Done!"));
tft.stopRefresh();
}
void ILI9341_t3DMA::refreshOnce(void) {
if (!autorefresh) {
writeRect( 0, 0, _width, _height, screen16);
}
}
#if defined SPI_HAS_TRANSACTION && !defined SPI_UART && !defined SOFTSPI
#define RF24_SPI_TRANSACTIONS
#endif
Also I can not tell from above if some of you are trying to use refreshOnce as the preferred way or because they are having issues with automatic refresh.
Do you know if this is the case - to make sure it is using SPI_Transactions? It seems like the CS pin isn't reset and the radio is responding to the Display's SPI transfers:
Without RF24_SPI_TRANSACTIONS #define'd it seems the code doesn't terminate the link.
Ok, it is a SILICON BUG.
CTAR1 is not used when using 16-BIT writes to PUSHR with DMA....
Looks like i have to find a workaround...
Ok, it is a SILICON BUG.
CTAR1 is not used when using 16-BIT writes to PUSHR with DMA....
The next version will remove the old ILI9341_t3.h, and all functions will be renamed to back to original names - means the "d" will be removed.