Frank's Random Wanderings

SSD1289 Landscape Mode & TFT Screen Rotation

SSD1289 TFT Display

A lot of the SSD1289 based TFT displays commonly available ship by default in portrait mode. Which is to say, 240 pixels across by 320 pixels deep. When you read the SSD1289 datasheet it would appear the chip defaults to landscape mode, however the display manufacturer can configure it however they like, and portrait mode is a common default.

Switching it to landscape mode isn’t as simple as it might appear. I had to do that recently for a project, and searching google, and various forums, I found I wasn’t the only one wondering how to accomplish it. With a little reading, trial & error I did work it out.

Here’s some simple C code to show one way of performing screen rotation on the SSD1289.

static char is_orientation_landscape = 0;	// portrait / landscape display orientation

void TFT_set_orientation_portrait ()
{
    is_orientation_landscape = 0;

    TFT_CS_0;
    Write_Command_Data (0x0001,0x2B3F);
    Write_Command_Data (0x0011,0x6070);
    Write_Command (0x0022);
    TFT_CS_1;
}


void TFT_set_orientation_landscape ()
{
    is_orientation_landscape = 1;

    TFT_CS_0;
    Write_Command_Data (0x0001,0x293F);
    Write_Command_Data (0x0011,0x6078);
    Write_Command (0x0022);
    TFT_CS_1;
}

The above code maintains a variable to keep track of whether it’s in portrait mode (is_orientation_landscape = 0) or landscape mode (is_orientation_landscape = 1). The above code also writes the “magic numbers” to the SSD2390 registers; read the SSD1289 datasheet to understand what those numbers mean. The macros TFT_CS_0 and TFT_CS_1 are simply for controlling the TFT ChipSelect line.

The reason for the is_orientation_landscape variable becomes clear in the code below.

void TFT_Set_Address(unsigned int PX1,unsigned int PY1,unsigned int PX2,unsigned int PY2)
{
    if (is_orientation_landscape) {
	Write_Command_Data (0x44,(PY2 << 8) + PY1 );   //Column address start2
	Write_Command_Data (0x45,PX1);                 //Column address start1
	Write_Command_Data (0x46,PX2);                 //Column address end2
	Write_Command_Data (0x4e,PY1);                 //Column address end1
	Write_Command_Data (0x4f,PX1);                 //Row address start2
    }
    else {
  	Write_Command_Data (0x44,(PX2 << 8) + PX1 );   //Column address start2
	Write_Command_Data (0x45,PY1);                 //Column address start1
	Write_Command_Data (0x46,PY2);                 //Column address end2
	Write_Command_Data (0x4e,PX1);                 //Column address end1
	Write_Command_Data (0x4f,PY1);                 //Row address start2
    }

    Write_Command (0x22);
}

The TFT_Set_Address() function is heavily used to set the corners of the "box" that subsequent pixels will be drawn into. When in landscape mode the X & Y positions must be transposed. Effectively, (X1, Y1, X2, Y2) in portrait mode becomes (Y1, X1, Y2, X2) in landscape mode. In landscape mode, as should be obvious, resolution is now 320 pixels across (X direction) by 240 pixels down (Y direction).

That's it. With these changes, the SSD1289 can be easily flipped between portrait and landscape mode.

3 thoughts on “SSD1289 Landscape Mode & TFT Screen Rotation

  1. TiX

    Thanks, that saved my time !!! Tried a lot before I found this.

    For information, it was wrong orientation for me, changed 180° with :

    WriteRegister(0x01, 0x6B3F);
    WriteRegister(0x11, 0x6078);

    SetArea method not changed.

    Best regards.

  2. Nils

    This seems kind of weird to me, aren’t there AMxx bits in this controller for direction control? This shifting stuff in set address.
    Also set address could be smaller:

    ssd1289_write_reg(0x4e, x);
    ssd1289_write_reg(0x4f, y);
    LCD_REG = 0x22; /* set register for RAM, next access to LCD_RAM is pixel data */

    Nils

Leave a Reply

Your email address will not be published. Required fields are marked *