• We recently switched our forum platform. If you experience any issues please email support@crystalfontz.com

text to CFAF176220U-020T

hfbroady

New member
I have the CFAF176220U-020T TFT display with the OTM2201A controller. I want to send simple Text to the display. The back light turns on, and this is as far as I got so far. The sample code that I have uses an SD card, but I don't need to display pictures or motion, just want to send text and change the color on the screen. Any help would be great, especially some very simple code. I'm using the PIC18f4520, with MPLAB and the MPLAB C18 complier (using C).

Port Assignments:

PORTC: DB0-DB7

PORTD: D0=/Reset, D1=/RD, D2=/WR, D3=RS, D4=/CS, D5= BL EN, D6=IMO

Here is what I have so far



Code:
#include pic18f4520
#pragma config LVP=ON

//#pragma config OSC = INTIO67


void write_command(unsigned char command)
{

/*  
CLR_CS;       // chip selected
  CLR_RS;       // set to write to the control registers
  SET_RD;       // not reading
 SET_WR;       // not writing yet
*/
	LATD = 0x07; //chip selected, set for command (RS), (RD) not reading, (WR) not writing

  LATC=0x00;   // write the command to the port

  
	LATD = 0x03; // bring write line low, clock in the command

  LATC=command;// write the command to the port

 
	LATD = 0x03; // bring write line low, clock in the command

 

	LATD = 0x19; // unselect chip, set for data
}
// ************************************************************************* //
void write_data(unsigned char data_h, unsigned char data_l)
{

		LATD = 0x07; //chip selected, set for command (RS), (RD) not reading, (WR) not writing
  
  LATC=data_h; // write the command to the port

	
		LATD = 0x03; // bring write line low, clock in the command

  LATC=data_l; // write the command to the port

	
		LATD = 0x03; // bring write line low, clock in the command
	
		LATD = 0x19; // unselect chip, set for data
}
// ************************************************************************* //
void display_color(unsigned char data_h, unsigned char data_l)
{
  unsigned int i, j;
  write_command(0x20);
  write_data(0x00,0x00);
  write_command(0x21);
  write_data(0x00,0x00);
  write_command(0x22);

  for(i=0;i<220;i++)
  {
    for(j=0;j<176;j++)
    {
      write_data(data_h,data_l);
    }
  }
}
//****************************************************************************//
void delay()
 {
	int i;
   	for (i=0; i<3000; i++)
	;
	
	
 }
// ************************************************************************* //
void initialize_display()
{
   
	LATD = 0x00; //Reset active low
   	delay();
   
	LATD = 0x01; //Reset off
 
	   	delay();
  
	LATD = 0x00; //Reset active low
  
	   	delay();

  write_command(0x11);  // Power Control 2 (P22, OTM2201A Datasheet)
  write_data(0x00,0x18);// Booster circuits not started automatically, controlled through PON0-3
												// Generate VCI1, VCI1 = +2.58v

  write_command(0x12);  // Power Control 3 (P22-23, OTM2201A Datasheet)
  write_data(0x00,0x00);// Generate VGH VCI1 x 5 (13.75v) / VGL VCI1 x -3 (-8.25v)
												// Freq. of step up 1 = 1:4, Freq. of step up 2 = 1:2, Freq. of step up 3 = 1:4

  write_command(0x13);  // Power Control 4 (P23-25, OTM2201A Datasheet)
  write_data(0x00,0x63);// clock cycle of external (RGB) interface (as default, unused)
												// Gamma voltage (GVDD < AVDD (VCI1*2)-0.3v) 1100011 = GVDD Voltage +4.45v

  write_command(0x14);  // Power Control 5 (P14, OTM2201A Datasheet)
  write_data(0x55,0x6A);// VCOMG = 0 ( Amplitude of VCOM = |VCOMH-VCOML| ), VCOMH = GVDD x 0.8690
												// VCMR = 0 (VCOMH determined by VCM6-0), VCOMH = GVDD x 1.074

  write_command(0x10);  // Power Control 1 (P21, OTM2201A Datasheet)
  write_data(0x08,0x00);// Constant current in op-amp Medium Fast 1
												// Not in stand by, not in deep stand by 
    delay();

  write_command(0x11);  // Power Control 2 (P22, OTM2201A Datasheet)
  write_data(0x01,0x18);// Start booster circuit 1
												// Generate VCI1, VCI1 = +2.58v
 	delay();

  write_command(0x11);  // Power Control 2 (P22, OTM2201A Datasheet)
  write_data(0x03,0x18);// Booster circuit 1 on, start VGH circuit
												// Generate VCI1, VCI1 = +2.58v
  	delay();

  write_command(0x11);  // Power Control 2 (P22, OTM2201A Datasheet)
  write_data(0x07,0x18);// Booster circuit 1, VGH on, start VGL circuit
												// Generate VCI1, VCI1 = +2.58v
  	delay();

  write_command(0x11);  // Power Control 2 (P22, OTM2201A Datasheet)
  write_data(0x0F,0x18);// Booster circuit 1, VGH, VGL on, Start VCL circuit
												// Generate VCI1, VCI1 = +2.58v
 	delay();

  write_command(0x11);  // Power Control 2 (P22, OTM2201A Datasheet)
  write_data(0x0F,0x38);// Booster circuit 1, VGH, VGL on, Start VCL circuit
												// Start amplifier circuit, Generate VCI1, VCI1 = +2.58v
  	delay();

  write_command(0x07);  // Display Control (P17, OTM2201A Datasheet)
  write_data(0x00,0x12);// FLM output disabled
												// Gate output Enabled, Normally black

  write_command(0x07);  // Display Control (P17, OTM2201A Datasheet)
  write_data(0x00,0x1A);// FLM output disabled
												// Gate output Enabled, 8 color mode selected, Normally black

  write_command(0x01);  // Driver Output Control Register (P14, OTM2201A Datasheet)
  write_data(0x01,0x1C);// Decrement Address counter 
												// 528x220 dots (176xRGBx220)

  write_command(0x03);  // Entry Mode (P16, OTM2201A Datasheet)
  write_data(0x10,0x30);// BGR (reversed color bits)
												// Increment automatically the address counter

  write_command(0x07);  // Display Control (P17, OTM2201A Datasheet)
  write_data(0x00,0x00);// FLM output disabled
												// Gate output disabled

  write_command(0x08);  // Blanking Control (P18, OTM2201A Datasheet)
  write_data(0x08,0x08);// 8 lines for the front porch
												// 8 lines for the back porch

  write_command(0x15);  // VCI Period (P28, OTM2201A Datasheet)
  write_data(0x00,0x20);// 
												// Sn=2, Vcom1=1/2, Vcom2=2/1, RGB=16dot clock

  write_command(0x36);  // Horizontal Window Address 1 (P32, OTM2201A Datasheet)           
  write_data(0x00,0xAF);// Set the horizontal start position of a window for memory access
												// 175

  write_command(0x37);  // Horizontal Window Address 2 (P33, OTM2201A Datasheet) 
  write_data(0x00,0x00);// Set the horizontal end position of a window for memory access
												// 0

  write_command(0x38);  // Vertical Window Address 1 (P33, OTM2201A Datasheet) 
  write_data(0x00,0xDB);// Set the vertical start position for memory access
												// 219

  write_command(0x39);  // Vertical Window Address 1 (P33, OTM2201A Datasheet) 
  write_data(0x00,0x00);// Set the vertical end opsition of a window for memory access
												// 0

  write_command(0x50);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x00,0x01);

  write_command(0x51);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x02,0x08);

  write_command(0x52);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x08,0x05);

  write_command(0x53);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x04,0x04);

  write_command(0x54);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x0c,0x0c);

  write_command(0x55);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x00,0x0c);

  write_command(0x56);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x01,0x00);

  write_command(0x57);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x04,0x00);

  write_command(0x58);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x11,0x08);

  write_command(0x59);  // Gamma Control (P34, OTM2201A Datasheet)
  write_data(0x05,0x0c);

  write_command(0x0F);  // Oscillator Control (P21, OTM2201A Datasheet)
  write_data(0x0F,0x01);// Freq = 453kHz x 1.29
												// Oscillator on

  write_command(0x07);  // Display Control (P17, OTM2201A Datasheet)
  write_data(0x00,0x12);// FLM output disabled
												// Gate output Enabled, Normally black

  write_command(0x07);  // Display Control (P17, OTM2201A Datasheet)
  write_data(0x00,0x17);// FLM output disabled
												// Gate output Enabled, Normal display, gate on, vcom on, display on


  write_command(0x22);  // GRAM Data (P30, OTM2201A Datasheet)

}






void main ()
{
             int loop = 1;
             initialize_display();
		
	while (loop == 1)
	{	

		
		display_color(0xff,0xff);  // change the color of the display to black

		
     }	
	
}

Thank you
Heath
(moderator adds code formatting.)
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 
Last edited:
I just took a quick look at the data sheet for this display, and it seems that this is a graphics-only type of controller. That means you would have to draw the text on the screen as bit patterns, using your own code, since there is no "text mode" or CGROM in the controller.

A lot of the TFT displays have remarkably similar interfaces and instruction sets, so you could use some of the sample graphic/text code that is posted on these forums. Here is an example thread that has some code for the CFAF320340, but it is a simple matter to change the defines for the screen dimensions.

You will have to also have fonts as part of your code (i.e. the bit patterns for the characters). Those are included in the sample files (the newest files are in post #28 of that thread).

https://forum.crystalfontz.com/showthread.php?6637-Text-graphic-C-code-for-CFAF320240

Actually, I found that I do have the CFAF176220 display, and have written some test code for it, but it is not posted here, and is actually based on the CFAF320 code, so I'm pointing you to the posted code for starters.

BTW, what I gather from your post is that you can't see anything on the screen yet... is that true? That's the first thing to fix, before trying to write text. Also, regarding putting characters on a graphics display, you will need much more than "very simple code".
 

hfbroady

New member
Yeah, when I power the TFT up all I see is back light. I'm not even sure how to get anything to display onto the screen. I don't have a storage device like a microSD card or anything. So not really sure how this will work. Is there a way to change the color with some code. I saw the datasheet and it's doesn't say where or how to change the color.

Also where In the datasheet did you see that is said graphics only.

I need to get better at reading datasheets.

Thanks
Heath
 
Yeah, when I power the TFT up all I see is back light. I'm not even sure how to get anything to display onto the screen.
That's what the code is for, but I suppose you knew that.
I don't have a storage device like a microSD card or anything. So not really sure how this will work.
Don't need external storage. The program is burned into flash memory on the CPU.
Is there a way to change the color with some code. I saw the datasheet and it's doesn't say where or how to change the color.
The way to change screen color is to write pixels of the color you want, to replace the current pixel color. To fill the screen with a new color, you'll have to perform 38720 write operations (176 * 220). The color is contained in the data that you write.
Also where In the datasheet did you see that is said graphics only. I need to get better at reading datasheets.
The datasheet doesn't explicitly say "graphics only". It also makes absolutely no mention of any built-in text mode, so you have to draw the conclusion yourself.

As I look a bit more at your test code, I see that it can't possibly work. I am curious about this:
PORTD: D0=/Reset, D1=/RD, D2=/WR, D3=RS, D4=/CS, D5= BL EN, D6=IMO
There is no signal on the interface called IMO. There is a signal called IM0 on the OTM2201A controller, but it is not brought out to the interface.

Anyway, your write_command() and write_data() functions have some serious problems. The /WR signal clocks data in on the rising edge; you don't bring the /WR signal high at all while data is on the bus. Also, at the end of the functions, you leave both /RD and /WR low, which is a bad idea.

I suggest you look more closely at the sample code in the data sheet, and the files in the thread I referenced, to see that the /WR signal needs to be taken LOW then HIGH for each data byte on the bus.

Also, in the initialize_display() function, your /reset signal seems to be inverted, although this will be corrected by the first data/command write.

If these fixes do not produce any results, then we'll have to look more closely at your code.
 

hfbroady

New member
The code that I got was write of the crystalfontz website. So I just copy and pasted that code. I will continue to work at this. I learn new code better when I have a WORKING examples to look at.
 
The code that I got was write of the crystalfontz website. So I just copy and pasted that code.
Based on your sample in the first post, I can see that is not true. You took working code and commented it out:
Code:
/*  
CLR_CS;       // chip selected
  CLR_RS;       // set to write to the control registers
  SET_RD;       // not reading
 SET_WR;       // not writing yet
*/
and substituted non working code:
Code:
	LATD = 0x07; //chip selected, set for command (RS), (RD) not reading, (WR) not writing
	LATC=0x00;   // write the command to the port
	LATD = 0x03; // bring write line low, clock in the command
	LATC=command;// write the command to the port
	LATD = 0x03; // bring write line low, clock in the command
	LATD = 0x19; // unselect chip, set for data
That is why your program does not function.
I will continue to work at this. I learn new code better when I have a WORKING examples to look at.
Yes, well the working example is there for you to use. If you wish, I can post MY version of "working code" also, but it is so similar to what you already have that it may not help.

If you have updated code that you want critiqued, post it, but please wrap it in "code" + "/code" formatting (change the quote marks to [ and ] characters, or go to the advanced editing option and use the "#" tool to add the code tags to your text).
 
Top