Author Topic: ILI9341 TFT Display and hardware scrolling  (Read 8750 times)

0 Members and 1 Guest are viewing this topic.

Offline MyElectronsFellOutTopic starter

  • Regular Contributor
  • *
  • Posts: 70
  • Country: gb
ILI9341 TFT Display and hardware scrolling
« on: July 14, 2016, 12:29:11 pm »
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: [Select]
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 right


TFT.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 high
tft_write(Address >> 8, DAT_MODE, Rx);      // Rx - Strobe Read Pin, Write is high
tft_write(Address & 0xFF, DAT_MODE, Rx);


}

   

 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1768
  • Country: se
Re: ILI9341 TFT Display and hardware scrolling
« Reply #1 on: July 15, 2016, 09:37:28 am »
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 datasheet here
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline MyElectronsFellOutTopic starter

  • Regular Contributor
  • *
  • Posts: 70
  • Country: gb
Re: ILI9341 TFT Display and hardware scrolling
« Reply #2 on: July 15, 2016, 10:54:43 am »
Check the datahseet link, it has the exact same table on pages 120 and 129.

My two functions look like this:

Code: [Select]
void TFT::tft_VertScrollingSetup(){

// Setup the area of screen defined for scrolling
tft_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.




 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1768
  • Country: se
Re: ILI9341 TFT Display and hardware scrolling
« Reply #3 on: July 15, 2016, 11:46:10 am »
Check the datahseet link, it has the exact same table on pages 120 and 129.
Yes, 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 to write parameters 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).
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 8409
Re: ILI9341 TFT Display and hardware scrolling
« Reply #4 on: July 15, 2016, 11:49:03 am »
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.
Quote
I don't understand why I have to continuously draw GPX data either in order to scroll the display.
If 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.
 

Offline MyElectronsFellOutTopic starter

  • Regular Contributor
  • *
  • Posts: 70
  • Country: gb
Re: ILI9341 TFT Display and hardware scrolling
« Reply #5 on: July 15, 2016, 12:04:19 pm »
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: [Select]
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 Start
tft_write(Line >> 8, DAT_MODE, Wx);
tft_write(Line & 0xFF, DAT_MODE, Wx);
// X End
tft_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 Start
tft_write(Line >> 8, DAT_MODE, Wx);
tft_write(Line & 0xFF, DAT_MODE, Wx);
// Y End
tft_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: [Select]
void TFT::tft_VertScrollingSetup(){

// Setup the area of screen defined for scrolling
tft_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);



}
 

Offline f1rmb

  • Regular Contributor
  • *
  • Posts: 180
  • Country: fr
Re: ILI9341 TFT Display and hardware scrolling
« Reply #6 on: July 15, 2016, 12:11:40 pm »
Hi

   I'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 library
Code: [Select]
// Did not pass in VSA as TFA+VSA=BFA must equal tk_TFT->height() (320)
// wTFA: zero from the top
// wBFA: zero from the bottom
void 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 16
SPI.write(wTFA);
SPI.write(ILI9341_TFTHEIGHT - (wTFA + wBFA));
SPI.write(wBFA);
SPI.setDataSize(0); // Reset datasize to 8
#else
writedata(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 ring
void 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 16
SPI.write(wVSP);
SPI.setDataSize(0); // Reset datasize to 8
#else
writedata(wVSP >> 8);
writedata(wVSP & 0xFF);
#endif
}


Code example:
Code: [Select]
....
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()));
else
tk_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 offset
tk_TFT->setVerticalScrollStartAddress(tk_TFT->getRotation() == 0 ? m_scrollOffset : ILI9341_TFTHEIGHT - m_scrollOffset);

}


Cheers
---
Daniel
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1768
  • Country: se
Re: ILI9341 TFT Display and hardware scrolling
« Reply #7 on: July 15, 2016, 12:13:04 pm »
If 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.
That 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 issued after the 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.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline MyElectronsFellOutTopic starter

  • Regular Contributor
  • *
  • Posts: 70
  • Country: gb
Re: ILI9341 TFT Display and hardware scrolling
« Reply #8 on: July 15, 2016, 12:37:39 pm »
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: [Select]
void TFT::tft_VertScrollingSetup(){

// Setup the area of screen defined for scrolling
tft_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 mode
tft_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 Start
tft_write(50 >> 8, DAT_MODE, Wx);
tft_write(50 & 0xFF, DAT_MODE, Wx);
// X End
tft_write(100 >> 8, DAT_MODE, Wx);
tft_write(100 & 0xFF, DAT_MODE, Wx);

tft_write(ILI9341_PASET, COM_MODE, Wx); // Y Set

// Y Start
tft_write(SCROLLING_TFA, DAT_MODE, Wx);
tft_write(SCROLLING_TFA & 0xFF, DAT_MODE, Wx);
// Y End
tft_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.
« Last Edit: July 15, 2016, 12:39:27 pm by MyElectronsFellOut »
 

Offline MyElectronsFellOutTopic starter

  • Regular Contributor
  • *
  • Posts: 70
  • Country: gb
Re: ILI9341 TFT Display and hardware scrolling
« Reply #9 on: July 15, 2016, 02:08:26 pm »
Ok, got this one solved!! Turns out was just messing up the numbers to define the scroll window.

thanks for your help guys.
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1768
  • Country: se
Re: ILI9341 TFT Display and hardware scrolling
« Reply #10 on: July 15, 2016, 03:17:01 pm »
Ok, got this one solved!! Turns out was just messing up the numbers to define the scroll window.

thanks for your help guys.
:-+ Glad you managed it!
Nandemo wa shiranai wa yo, shitteru koto dake.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf