CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help with LCD graphics

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
cbarberis



Joined: 01 Oct 2003
Posts: 172
Location: Punta Gorda, Florida USA

View user's profile Send private message Send e-mail

Help with LCD graphics
PostPosted: Tue Nov 25, 2008 7:50 pm     Reply with quote

Hello,

I seem to have a nasty problem with a graphics driver I recently modified to drive a 128X64 graphical display, using the Sitronix ST7920 controller. I had originally found some code in the forum posted by javierviana for a similar controller (different display) I was able to easily modify this code to use with the Crystalfontz 144X32 graphical display by making some changes to the original code and it seems to work quite nicely. Since, I have acquired another module from Crystalfontz (CFAG12864JTMI) which is basically the same controller but the only difference is that it is a 128X64, the controller is really a 256X32 bitmap split into an upper screen which is 32 rows in the vertical space and 128 columns in the horizontal space. The ST7920 is not a very easy device to work, at least not their chinese translated data sheets. The way you get 128X64 pixels is by addressing the vertical from 0 to 31 and the horizontal from 0 to 127 when the horizontal address (16bit field) reaches 128 it automatically indexes the bottom half of the screen (Vert pos 32) and the vertical then steps from 0-31 or 32-64 while the horizontal goes from 128 to 256, in other words; to light up a pixel at location X=100 and Y=50 the real address would be X=227, Y=19. The problem I seem to have is most likely related to glcd_update() and the way the bitfield for the union/structure called gdram, it appears that I am missing the point with this bit field as I can only seem to address the upper half of the display, but not the lower, I am sure this is probably a simple problem, but I seem to be really bogged down with the way this pixel map is realized using the struct gdram, any hints or suggestions would be great help, specially if you have used this device.

Thank you Confused
Code:
************************************************************************************************************************************
/***************************************************************************
*
*
*
* This file contains drivers for using a CrystalFontz CFAG12864JTMI
* that uses a Sitronix ST7920 display controller. The CFAG12864JTMI is 128 by
* 64 pixels.
* The driver treats the upper left pixel as (0,0).
*
* This display maps out to a 32X256 bit map or two 32X128 screens stacked
*
*    LCD Pin connections:
*  1: VSS is connected to GND
*  2: VDD is connected to +5V
*  3: V0  - LCD operating voltage (Constrast adjustment)
*  4: R/S - Data or Instruction is connected to C7
*  5: R/W - Read or Write is connected to C6
*  6: Enable is connected to C5
*  7-14: Data Bus 0 to 7 is connected to port D
*  15: Positive voltage for LED backlight is connected to +5V
*  16: Negavtive voltage for LED backlight is connected to GND
*
*   This code was copied and modified from original source by javierviana
*   http://www.ccsinfo.com/forum/viewtopic.php?t=32819&highlight=st7920
*
*  glcd_init () Must be called before any other function.
*
*  glcd_pixel (x,y,color) Sets the pixel to the given color.
*  color can be ON or OFF
*
*  glcd_fillScreen (color) Fills the entire LCD with the given color.
*  color can be ON or OFF
*
*****************************************************************************/

#define GLCD_RS     RC7   // Display Data / Control Data.
#define GLCD_RW     RC6   // Read / Write
#define GLCD_E      RC5   // Enable Signal.

#define GLCD_WIDTH   128

#define RS_FUNCTION   0
#define RS_DATA      1
#define RW_WRITE   0
#define RW_READ      1
#define TRIS_READ   0xFF
#define TRIS_WRITE   0x00
#define XVAL 16  // 16 X 16 or 256 for there is 8 word values for the upper and lower
#define YVAL 32

// Color Values
#define ON   1
#define OFF   0

typedef union
{
  int16 word;
  int8 byte[2];
} Dots;

typedef struct
{
  int1 refresh;
  Dots pix[YVAL][XVAL];   // Max dimensions for display (x,y) = (128,32)
  } GD_RAM;             //  (0,0) corresponds to upper lefthand corner.

GD_RAM gdram;


/*----------------------------------------------------------------------------------------------
 * glcd_readByte
 *
 * Reads a byte of data from the LCD.
 *
 * In/Out:
 *
 * Return:   A byte of data read from the LCD.
 *
 *--------------------------------------------------------------------------------------------*/

unsigned int8 glcd_readByte (unsigned int8 address)
{
  unsigned int8 data;   // Stores the data read from the LCD

  set_tris_b (TRIS_READ);   // Set PORTB to input
  delay_us(15);
  GLCD_RS = address;
  GLCD_RW = RW_READ;      // Set for reading
  delay_us(50);
  GLCD_E = 1;      // Pulse the enable pin
  delay_us(50);
  data = PORTB;      // Get the data from the display's output register
  GLCD_E = 0;
  delay_us(15);
  GLCD_RS = 1;
  return (data);
}

/*----------------------------------------------------------------------------------------------
 * Function Name:   CheckBusyFlag()
 *
 * Function:   Reads the status of bit 7 to test busy flag
 *
 * In/Out:
 *
 * Return:  Flagdata
 *
 *
 *
 *--------------------------------------------------------------------------------------------*/

unsigned int8 CheckBusyFlag ()
{
  unsigned int8 Flagdata;   // flag data value

  set_tris_d (TRIS_READ);   // Set PORTB to input
  delay_us(15);
  GLCD_RS = 0;
  GLCD_RW = RW_READ;      // Set for reading
  delay_us(5);
  GLCD_E = 1;      // Pulse the enable pin
  delay_us(15);
  Flagdata = (PORTD & 0x80); // mask bit 7 to test busy flag data from the display's output register
  delay_us(15);
  GLCD_E = 0;
  delay_us(15);
  GLCD_RS = 1;
  return (Flagdata);
}


/*----------------------------------------------------------------------------------------------
 * glcd_writeByte
 *
 * Write a byte of data to the LCD.
 *
 *   - data   (in): the byte of data to write.
 *
 *
 *--------------------------------------------------------------------------------------------*/

void glcd_writeByte (unsigned int8 address, unsigned int8 data)
{
  GLCD_RS = RS_FUNCTION;
  GLCD_E = 0;
  while ( CheckBusyFlag () ) ;   // Whait Busy Flag = FALSE!
  set_tris_d (TRIS_WRITE);   // Set PORTB to output
  delay_us(10);
  GLCD_RS = address;
  GLCD_RW = RW_WRITE;      // Set for writing
  delay_us(1);
  GLCD_E = 1;
  delay_us(5);
  PORTD = data;         // Put the data on the port
  delay_us(10);
  GLCD_E = 0;         // Pulse the enable pin
  delay_us(5);
  GLCD_RW = RW_READ;

}



/*----------------------------------------------------------------------------------------------
 glcd_fillScreen
 *
 *  Fill the LCD screen with the passed in color.
 *
 *   - color   (in):
 *          ON  - turn all the pixels on.
 *          OFF - turn all the pixels off.
 *
 *--------------------------------------------------------------------------------------------*/

void glcd_fillScreen (unsigned int1 color)
{
  int8 v, h;
  int16 d;


  d = (color == ON ? 0xFFFFL : 0x0000L);

  for (v=0; v < YVAL; v++)
  {
    for (h=0; h < XVAL; h++)
    {
      gdram.pix[v][h].word = d;
    }
  }
  gdram.refresh = TRUE;
}


/*----------------------------------------------------------------------------------------------
 * glcd_update
 *
 * Update the LCD with data from the display cache.
 *
 *--------------------------------------------------------------------------------------------*/

void glcd_update ()
{
  int8 v, h,k;


  if (gdram.refresh)
  {
    for (v=0; v <YVAL; v++)
    {
      glcd_writeByte (RS_FUNCTION, 0x80 | v);   // Set Vertical Address.
      glcd_writeByte (RS_FUNCTION, 0x80 | 0);   // Set Horizontal Address.

      for (h=0; h <XVAL; h++)
      {
        glcd_writeByte (RS_DATA, gdram.pix[v][h].byte[1]);   // Write High Byte.
        glcd_writeByte (RS_DATA, gdram.pix[v][h].byte[0]);   // Write Low Byte.
      }
    }
    gdram.refresh = FALSE;
  }
}
cbarberis



Joined: 01 Oct 2003
Posts: 172
Location: Punta Gorda, Florida USA

View user's profile Send private message Send e-mail

PostPosted: Tue Nov 25, 2008 8:12 pm     Reply with quote

////Missing code from previous message (got accidentally left out)

Code:
/*----------------------------------------------------------------------------------------------
 * glcd_init
 *
 * Initialize LCD.
 *
 *   - mode   (in): OFF/ON - Turns the LCD off/on.
 *
 * Call before using any other LCD function.
 *
 *--------------------------------------------------------------------------------------------*/

void glcd_init ()
{
  set_tris_d (TRIS_WRITE);   // PORTB as output.
  GLCD_RS = RS_FUNCTION;
  GLCD_RW = RW_WRITE;
  GLCD_E = 0;
  delay_ms (40);

  glcd_writeByte (RS_FUNCTION, 0x30);    // Specify 8 bit interface and basic instruction set.
  delay_ms (10);
  glcd_writeByte (RS_FUNCTION, 0x30);    // Specify 8 bit interface and basic instruction set.
  delay_ms (10);
  glcd_writeByte (RS_FUNCTION, 0x0C);    // Specify Display on, Cursor off and Blink off.
  delay_ms (10);
  glcd_writeByte (RS_FUNCTION, 0x01);    // Display clear.
  delay_ms (10);
  glcd_writeByte (RS_FUNCTION, 0x06);    // AC Increase (cursor move right), don't shift the display.
  delay_ms (10);
  glcd_writeByte (RS_FUNCTION, 0x34);    // Select extended instruction set.
  delay_ms (10);
  glcd_writeByte (RS_FUNCTION, 0x36);    // Graphic display ON.
  delay_ms (10);

  glcd_fillScreen (OFF);
  glcd_update ();
}


/*----------------------------------------------------------------------------------------------
 * Turn a pixel on a graphic LCD on or off.
 *
 *
 *   - x   (in): the x coordinate of the pixel.
 *   - y   (in): y - the y coordinate of the pixel.
 *   - color   (in): ON or OFF.
 *--------------------------------------------------------------------------------------------*/

void glcd_pixel(int8 x, int8 y, int1 color)
{
  int8 v, h, b;

  v = y;
  h = x/16;
  b = 15 - (x%16);
 
 // if(v>31){h += 128; v-= 32;} //Although this works to some point the update does not

  // Modify the actual word.
  if (color == ON) bit_set (gdram.pix[v][h].word, b);
  else bit_clear (gdram.pix[v][h].word, b);

  gdram.refresh = TRUE;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 25, 2008 9:51 pm     Reply with quote

Can you post the manufacturer and part number of the LCD (not the
chipset) that you are currently trying to make work ? If possible,
post a link to the webpage for the LCD.
cbarberis



Joined: 01 Oct 2003
Posts: 172
Location: Punta Gorda, Florida USA

View user's profile Send private message Send e-mail

PostPosted: Tue Nov 25, 2008 10:21 pm     Reply with quote

Thank you pcm programmer, here is the link:
http://www.crystalfontz.com/product/CFAG12864JTMITT.html
cbarberis



Joined: 01 Oct 2003
Posts: 172
Location: Punta Gorda, Florida USA

View user's profile Send private message Send e-mail

PostPosted: Wed Nov 26, 2008 11:47 am     Reply with quote

FOUND THE REAL PROBLEM!!!!!!!!!!!!!!!!

The reason why my graphics screen only works on only the upper half has nothing to do with the actual LCD driver code routines, the real isuue is that any calling routines to place pixels in the screen have to be translated as follows:

For line segments where (x1,y1,x2,y2) you must do the following:
if(y1>31){x1 += 128; y1 -= 32;}
if(y2>31){x2 += 128; y2 -= 32;}
For pixel positioning, where (x,y) you must do the following:
if(y>31){x += 128; y -= 32;}

The above have to be done in the graphic drawing routines (Graphics.c)
I will post a new driver and graphics.c once I get this going and it's tested, so others do not have to suffer like I did. Rolling Eyes Rolling Eyes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group