ILI9341 TFT Display and hardware scrolling - Page 1
Forum section: electronics / projects

author: MyElectronsFellOut
author_rank: Regular Contributor
timestamp: July 14, 2016, 12:29:11 pm
content: Greetings earthlings. I'm using the TFT touchscreen from Displaytech DT028ATFT. It has the ILI9341 Display Driver.The issue I am having is with hardware scrolling. Page 120 on the datasheet. I am trying to get the display to scroll smoothly (ideally when the touchscreen is activated) and i'm having limited success. So far, the display will respond and jump around a bit when I drag my finger along the screen.I'm trying to get a grip on this so though I would try just scrolling the screen indefinitely. But it won't work. I also noticed that, when using the touchscreen, it would only scroll if my main loop was continuously drawing to the screen. (The touchscreen is on a rising edge ISR). So not drawing anything at all within the main loop meant that it wouldn't scroll at all.I tried therefore simply writing display data to the screen followed by the scroll screen commands within the main loop and ... nothing.The datasheet is pretty sh*t if i'm being honest. It looks like my code follows the flow charts within but obviously I'm doing something wrong.I have setup the screen to parallel mode (18-bit color).My code.Code:void PIOA_Handler(){// Check it was PA20 that generated the Interrupt.if(((PIOA->PIO_ISR & PIO_PA20) == PIO_PA20) && TFT.Touched == false){PIOA->PIO_IDR = PIO_PA20;TFT.Touched = true;TFT.TS_GetCoordinates();x1 = TFT.TS_Y;TFT.TS_GetCoordinates();x2 = TFT.TS_Y;if(x2 < (x1 - 5)){// Left to rightTFT.tft_ScrollScreen();}PIOA->PIO_IER = PIO_PA20;TFT.Touched = false;}}void main(){while (1) {TFT.tft_FillArea(10, 50, 150, 20, RED);}}void TFT::tft_ScrollScreen(){tft_write(0x37, COM_MODE, Wx); // Wx - Stobe Write pin, Read pin is hightft_write(Address >> 8, DAT_MODE, Rx); // Rx - Strobe Read Pin, Write is hightft_write(Address & 0xFF, DAT_MODE, Rx);}

author: newbrain
author_rank: Super Contributor
timestamp: July 15, 2016, 09:37:28 am
content: Just a couple of basic observations:The code toggles the /RD line for 0x37 cmd parameters, that's most probably an error on page 120 and 129 of the datasheet.In the table on page 84 the /WR line is used (as for any other write operation!)I do not see in the posted code the definition of the scroll area (command 0x33), but the reset value might good for your application.BTW, You can find a more up-to-date datasheethere

author: MyElectronsFellOut
author_rank: Regular Contributor
timestamp: July 15, 2016, 10:54:43 am
content: Check the datahseet link, it has the exact same table on pages 120 and 129.My two functions look like this:Code:void TFT::tft_VertScrollingSetup(){// Setup the area of screen defined for scrollingtft_write(ILI9341_VSCRDEF, COM_MODE, Wx);tft_write(SCROLLING_TFA >> 8, DAT_MODE, Rx);tft_write(SCROLLING_TFA & 0xFF, DAT_MODE, Rx);tft_write(SCROLLING_AREA >> 8, DAT_MODE, Rx);tft_write(SCROLLING_AREA & 0xFF, DAT_MODE, Rx);tft_write(SCROLLING_BFA >> 8, DAT_MODE, Rx);tft_write(SCROLLING_BFA & 0xFF, DAT_MODE, Rx);}void TFT::tft_ScrollScreen(uint16_t Line){tft_write(0x37, COM_MODE, Wx);tft_write(Line >> 8, DAT_MODE, Rx);tft_write(Line & 0xFF, DAT_MODE, Rx);}I tried changing from Rx toggle to Wx toggle, and no joy. I can scroll the display but only under the circumstances mentioned. For some reason, I also can't seem to specify the 'Region' I wan to scroll. It's the whole screen or nothing.I don't understand why I have to continuously draw GPX data either in order to scroll the display.

author: newbrain
author_rank: Super Contributor
timestamp: July 15, 2016, 11:46:10 am
content: Quote from: MyElectronsFellOut on July 15, 2016, 10:54:43 amYes, that was my point. I'm pretty much convinced that's an error (two, actually) in the DS.As I said, look at the table on page 84: for both commands (0x33 and 0x37) only the /WR line is used. It makes no sense to use the /RD line towriteparameters to the controller.As an example, for the ILI9481 the same commands only use /WR.Have you changed Rx to Wx in both functions?The erratic scrolling could be due to the controller waiting for writes to complete the commands, and getting confused by subsequent operations.The code seems ok (at least that couple of functions), but could you post your complete minimal (i.e. just 1. init, 2. paint sth, 3. loop: delay, scroll) program?Unfortunately, I'm away from home and cannot test on my F429 discovery (that uses a 9341).

author: amyk
author_rank: Super Contributor
timestamp: July 15, 2016, 11:49:03 am
content: I would not be surprised if hardware scrolling was either buggy or not present at all, since this feature is relatively rarely used today, but a quick Google reveals others using the feature, so perhaps you could also learn from their code.QuoteIf you look at the flow chart in the datasheet, that's exactly what it says. It seems this scrolling feature only affects where data gets written into the display RAM, it does not change how it gets scanned.

author: MyElectronsFellOut
author_rank: Regular Contributor
timestamp: July 15, 2016, 12:04:19 pm
content: Ok;Seems I don't have to keep writing GPX data to scroll the screen. It is now working (Yay!). From my Scroll Screen function, I was missing the Column set and page set functions, along with the RAMWR function.Code:void TFT::tft_ScrollScreen(uint16_t Line){tft_write(0x37, COM_MODE, Wx);tft_write(Line >> 8, DAT_MODE, Wx);tft_write(Line & 0xFF, DAT_MODE, Wx);// X Starttft_write(Line >> 8, DAT_MODE, Wx);tft_write(Line & 0xFF, DAT_MODE, Wx);// X Endtft_write((Line+1) >> 8, DAT_MODE, Wx);tft_write((Line+1) & 0xFF, DAT_MODE, Wx);tft_write(ILI9341_PASET, COM_MODE, Wx);// Y Set// Y Starttft_write(Line >> 8, DAT_MODE, Wx);tft_write(Line & 0xFF, DAT_MODE, Wx);// Y Endtft_write((Line+1) >> 8, DAT_MODE, Wx);tft_write((Line+1) & 0xFF, DAT_MODE, Wx);tft_write(ILI9341_RAMWR, COM_MODE, Wx);// Write to RAM}I'm now struggling to set the "area" for scrolling. I think you were right about the Wx Rx pin, as I've changed it to Wx in the scrolling function.I'm now guessing that this function isn't correct and the flow charts aren't helping lol.Code:void TFT::tft_VertScrollingSetup(){// Setup the area of screen defined for scrollingtft_write(ILI9341_VSCRDEF, COM_MODE, Wx);tft_write(SCROLLING_TFA >> 8, DAT_MODE, Wx);tft_write(SCROLLING_TFA & 0xFF, DAT_MODE, Wx);tft_write(SCROLLING_AREA >> 8, DAT_MODE, Wx);tft_write(SCROLLING_AREA & 0xFF, DAT_MODE, Wx);tft_write(SCROLLING_BFA >> 8, DAT_MODE, Wx);tft_write(SCROLLING_BFA & 0xFF, DAT_MODE, Wx);}

author: f1rmb
author_rank: Regular Contributor
timestamp: July 15, 2016, 12:11:40 pm
content: HiI've spend some time to support scrolling for a small gps toolbox I'm working on, using a STM32F1x with an ILI9341. I've a NMEA monitor that uses scrolling.Here is some small piece of code that could help you to fix your problem.Added to the driver libraryCode:// Did not pass in VSA as TFA+VSA=BFA must equal tk_TFT->height() (320)// wTFA: zero from the top// wBFA: zero from the bottomvoid ILI9341_STM::setVerticalScrollDefinition(uint16_t wTFA, uint16_t wBFA){writecommand(ILI9341_VSCRDEF); // Vertical Scroll definition.#if defined (__STM32F1__)*dcport |= dcpinmask;*csport &= ~cspinmask;SPI.setDataSize(SPI_CR1_DFF); // Set datasize to 16SPI.write(wTFA);SPI.write(ILI9341_TFTHEIGHT - (wTFA + wBFA));SPI.write(wBFA);SPI.setDataSize(0); // Reset datasize to 8#elsewritedata(wTFA >> 8);writedata(wTFA & 0xFF);writedata((ILI9341_TFTHEIGHT - (wTFA + wBFA)) >> 8);writedata((ILI9341_TFTHEIGHT - (wTFA + wBFA)) & 0xFF);writedata(wBFA >> 8);writedata(wBFA & 0xFF);#endif}// The command will take effect on the next Panel Scan.// wVSP: address offset start in the buffer ringvoid ILI9341_STM::setVerticalScrollStartAddress(uint16_t wVSP){writecommand(ILI9341_VSCRSADD); // Vertical Scroll definition.#if defined (__STM32F1__)*dcport |= dcpinmask;*csport &= ~cspinmask;SPI.setDataSize(SPI_CR1_DFF); // Set datasize to 16SPI.write(wVSP);SPI.setDataSize(0); // Reset datasize to 8#elsewritedata(wVSP >> 8);writedata(wVSP & 0xFF);#endif}Code example:Code:....ResetScrolling(){...tk_TFT->setVerticalScrollStartAddress(0);tk_TFT->setVerticalScrollDefinition(0, 0);...}Redraw(){....if (tk_TFT->getRotation() == 0)tk_TFT->setVerticalScrollDefinition(p.GetY(), ILI9341_TFTHEIGHT - (p.GetY() + s.GetHeight()));elsetk_TFT->setVerticalScrollDefinition(ILI9341_TFTHEIGHT - (p.GetY() + s.GetHeight()), p.GetY());// Set scroll offset_scroll();}void tkWidgetTerminal::_scroll(){tkPoint p = tkWidgetDecoratedWindow::GetDrawableCoords();tkSize s = tkWidgetDecoratedWindow::GetDrawableSize();// Clear line// We clear the line first, even if it's on top position, because scroll offset will be effective on next Panel Scan.tk_TFT->fillRect(m_col, m_row, (p.GetX() + s.GetWidth()) - m_col, FONTHEIGHT_SMALL, ILI9341_COLOR_BLACK);// Set display's scroll offsettk_TFT->setVerticalScrollStartAddress(tk_TFT->getRotation() == 0 ? m_scrollOffset : ILI9341_TFTHEIGHT - m_scrollOffset);}Cheers---Daniel

author: newbrain
author_rank: Super Contributor
timestamp: July 15, 2016, 12:13:04 pm
content: Quote from: amyk on July 15, 2016, 11:49:03 amThat seems quite strange, and would make the feature a bit pointless: if I have to rewrite the whole image, where's the benefit of HW scrolling?In addition to this, in both flow charts, the Vertical Scrolling Start Address (0x37) command is issuedafterthe image data has been written: if it only affected the writing, what would be the point?Still, those ILItek DS are really not a pinnacle of clarity (a slight understatement...), and I can't verify "in corpore vivo"...OK obsolete post (ninjaed twice!), but sent for the record.

author: MyElectronsFellOut
author_rank: Regular Contributor
timestamp: July 15, 2016, 12:37:39 pm
content: Ninjaed... lol.Disregard my last post, I didn't need the column and page address set commands in the scrolling function. It's still working so i'm not sure whats going on with that.Still left with the same issue of setting the actual area now. By default it's the entire screen. But I want to limit it to a particular area. Heres my code thus far..Code:void TFT::tft_VertScrollingSetup(){// Setup the area of screen defined for scrollingtft_write(ILI9341_VSCRDEF, COM_MODE, Wx);tft_write(SCROLLING_TFA >> 8, DAT_MODE, Wx);tft_write(SCROLLING_TFA & 0xFF, DAT_MODE, Wx);tft_write((ILI9341_TFTWIDTH - (SCROLLING_TFA + SCROLLING_BFA)) >> 8, DAT_MODE, Wx); // TFT WIDTH as working in landscape modetft_write((ILI9341_TFTWIDTH - (SCROLLING_TFA + SCROLLING_BFA)) & 0xFF, DAT_MODE, Wx);tft_write(SCROLLING_BFA >> 8, DAT_MODE, Wx);tft_write(SCROLLING_BFA & 0xFF, DAT_MODE, Wx);// Below seems to be required in datasheet? Setting the actual window?tft_write(ILI9341_CASET, COM_MODE, Wx);// X Set// X Starttft_write(50 >> 8, DAT_MODE, Wx);tft_write(50 & 0xFF, DAT_MODE, Wx);// X Endtft_write(100 >> 8, DAT_MODE, Wx);tft_write(100 & 0xFF, DAT_MODE, Wx);tft_write(ILI9341_PASET, COM_MODE, Wx);// Y Set// Y Starttft_write(SCROLLING_TFA, DAT_MODE, Wx);tft_write(SCROLLING_TFA & 0xFF, DAT_MODE, Wx);// Y Endtft_write((SCROLLING_TFA + SCROLLING_AREA) >> 8, DAT_MODE, Wx);tft_write((SCROLLING_TFA + SCROLLING_AREA) & 0xFF, DAT_MODE, Wx);tft_write(ILI9341_RAMWR, COM_MODE, Wx);// Write to RAM}Net result when implementing this function... Srolling doesnt work.

author: MyElectronsFellOut
author_rank: Regular Contributor
timestamp: July 15, 2016, 02:08:26 pm
content: Ok, got this one solved!! Turns out was just messing up the numbers to define the scroll window.thanks for your help guys.

author: newbrain
author_rank: Super Contributor
timestamp: July 15, 2016, 03:17:01 pm
content: Quote from: MyElectronsFellOut on July 15, 2016, 02:08:26 pmGlad you managed it!