View previous topic :: View next topic |
Author |
Message |
dezso
Joined: 04 Mar 2010 Posts: 102
|
SED1335 driver (with anti-flicker) |
Posted: Sat Mar 27, 2010 12:00 pm |
|
|
I got my 1335 up and running, works very good, except for fast screen update, serious flicker affecting the whole screen, not that noticeable but I see it !
I have been searching for a solution. The D6 busy check what included in the sed1335.c is not working for me. As soon as I try to check for busy bit before write, the whole screen stops working.
Found this link last night, http://www.microchip.com/forums/tm.aspx?m=432421, anyone have any input on this flicker problem ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 27, 2010 10:12 pm |
|
|
If you want help, you need to tell people how to duplicate the problem.
Tell us what sed1335 driver you're using. If it's not the CCS driver,
then post a link to it. Also post a small, compilable test program
that uses the driver and demonstrates the problem. The test program
must compile with no errors if we copy and paste it into MPLAB.
Post the absolute minimal test program that shows the problem.
(no excess Wizard code).
Also post your compiler version. |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sun Mar 28, 2010 7:35 pm |
|
|
http://www.youtube.com/watch?v=Sd6eYOah_xI
I'm back to the original SED1335.c found in the drivers directory, the file modified but not changed, I only added new function to it, like my lcd has a built in vee gen ic and have to initialize it first.
The graphic.c also has new functions but not modified.
Note the horizontal white spots flicker on the black area !
I have this problem since day one ! could be the display ?
CCS PCH 4.105, |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sun Mar 28, 2010 10:04 pm |
|
|
Here it is.
Just the basics.
http://www.youtube.com/watch?v=BDIrCUJ_zZw
Main.c
Code: | /////////////////////////////////////////////////////////////////////////
//// Auarium Controller ////
//// Monitor PH,Temp, Salt and controll pumps and lights ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright non ////
/////////////////////////////////////////////////////////////////////////
#include <18F448.h>
#fuses H4,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#pragma use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
/////////////////////////////////////////////////////////////////////////
#define LARGE_LCD
#include <C:\Projects\GLCD_CCS\GlobalVariables.h>
#include <C:\Projects\GLCD_CCS\STRING.H>
#include <C:\Projects\GLCD_CCS\SED1335.C>
#include <C:\Projects\GLCD_CCS\GRAPHICS.C>
#include <C:\Projects\GLCD_CCS\MATH.H>
/////////////////////////////////////////////////////////////////////////
// Main Program
/////////////////////////////////////////////////////////////////////////
void main()
{
setup_adc_ports(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
SET_TRIS_B( 0xff );
glcd_init(ON); // Must initialize the LCD
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
DELAY_MS(500);
glcd_fillScreenText("#");
/////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////
for(;;)
{
sprintf(tempc, "Hello DDS");
glcd_text57(10, 70, tempc, 4,on);
delay_ms(10);
}
} |
sed1335.c
Code: | /////////////////////////////////////////////////////////////////////////
//// SED1335.c ////
//// ////
//// Example drivers for the SED1335 LCD controller on an Ampire ////
//// AG-320240A1 display. ////
/////////////////////////////////////////////////////////////////////////
//// ////
//// glcd_init(mode) ////
//// * Must be called before any other function. ////
//// - mode can be ON or OFF to turn the LCD on or off ////
//// ////
//// 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 ////
//// ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#ifndef SED1335
#define SED1335
#ifndef GLCD_WIDTH
#define GLCD_WIDTH 224
#endif
#ifndef GLCD_HEIGHT
#define GLCD_HEIGHT 240
#endif
#ifndef GLCD_CHAR_WIDTH
#define GLCD_CHAR_WIDTH 8
#endif
#ifndef GLCD_CHAR_HEIGHT
#define GLCD_CHAR_HEIGHT 8
#endif
#ifndef GLCD_RST
#define GLCD_RST PIN_C4
#endif
#ifndef GLCD_RD
#define GLCD_RD PIN_C2
#endif
#ifndef GLCD_WR
#define GLCD_WR PIN_C1
#endif
#ifndef GLCD_CS
#define GLCD_CS PIN_C3
#endif
#ifndef GLCD_A0
#define GLCD_A0 PIN_C0
#endif
#ifndef ON
#define ON 1
#endif
#ifndef OFF
#define OFF 0
#endif
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// The following defines setup the memory used by different regions
// Currenty one text area is defined at the beginning of memory
// and a graphics area follows immediately after
/////////////////////////////////////////////////////////////////////////
#define GLCD_TEXT_ADDR 0x0000
#define GLCD_GRAPHICS_ADDR GLCD_WIDTH * GLCD_HEIGHT / 64
#define GLCD_GRAPHICS_ADDR_END GLCD_GRAPHICS_ADDR + (GLCD_WIDTH * GLCD_HEIGHT / 8)
/////////////////////////////////////////////////////////////////////////
#define Max_749_ADJ PIN_A5
#define Max_749_CNTRl PIN_E0
/////////////////////////////////////////////////////////////////////////
#if GLCD_CHAR_WIDTH < 9
#define GLCD_CR (GLCD_WIDTH/8 - 1)
#else
#define GLCD_CR (GLCD_WIDTH/4 - 2)
#endif
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
//#define set_command(); output_high(GLCD_A0): status_d = 1;
//#define set_data(); output_low(GLCD_A0): status_d = 0;
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
int8 glcd_readByte();
void glcd_sendByte(int8 data);
void glcd_fillScreen(int1 color);
void glcd_fillScreenText(char c);
void setCursorAddress(int16 addr);
void glcd_pixel(int16 x, int16 y, int1 color);
int8 getData(int16 addr);
void glcd_sendCMD(int8 cmd);
int8 getStatus();
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
void glcd_systemSetup();
void glcd_scrollSetup();
void glcd_overlaySetup();
void glcd_power(int1 mode);
void glcd_cursorDirection(int8 dir);
void glcd_cursorForm(int8 width, int8 height);
void setData(int16 addr, int8 data);
int status_d;
/////////////////////////////////////////////////////////////////////////
#define GLCD_CMD_SYSTEM 0x40 // General system settings
#define GLCD_CMD_SLEEP 0x53 // Enter into standy mode
#define GLCD_CMD_DISP_OFF 0x58 // Turn the display off
#define GLCD_CMD_DISP_ON 0x59 // Turn the display on
#define GLCD_CMD_SCROLL 0x44 // Setup text and graphics address regions
#define GLCD_CMD_CSR_FORM 0x5D // Set cursor size
#define GLCD_CMD_CSRDIR_RIGHT 0x4C // Cursor moves right after write to display memory
#define GLCD_CMD_CSRDIR_LEFT 0x4D // Cursor moves left after write to display memory
#define GLCD_CMD_CSRDIR_UP 0x4E // Cursor moves up after write to display memory
#define GLCD_CMD_CSRDIR_DN 0x4F // Cursor moves down after write to display memory
#define GLCD_CMD_CGRAM_ADDR 0x5C // Configure character generator RAM address
#define GLCD_CMD_HDOT_SCR 0x5A // Set horizontal scroll rate
#define GLCD_CMD_OVERLAY 0x5B // Configure how layers overlay
#define GLCD_CMD_SET_CSR_ADDR 0x46 // Set the cursor address
#define GLCD_CMD_GET_CSR_ADDR 0x47 // Read the cursor address
#define GLCD_CMD_DISPLAY_WRITE 0x42 // Write to display memory
#define GLCD_CMD_DISPLAY_READ 0x43 // Read from display memory
void set_command()
{
output_high(GLCD_A0);
status_d = 1;
}
void set_data()
{
output_low(GLCD_A0);
status_d = 0;
}
// Purpose: Set the MAX749 LCD voltage generator contrast voltage
// Inputs: The byte of data to write
void glcd_contrast(byte contrast)
{ //byte contrast;
set_tris_b(0x00);
output_low(Max_749_ADJ);
delay_cycles(10);
output_low(Max_749_CNTRL);
delay_cycles(10);
output_low(Max_749_CNTRL);
delay_cycles(10);
output_high(Max_749_ADJ);
delay_cycles(10);
output_high(Max_749_CNTRL);
do {
output_low(Max_749_ADJ);
delay_cycles(4);
output_high(Max_749_ADJ);
}
while(contrast--);
}
// Purpose: Initialize the controller
// Inputs: The initialization mode
// OFF - Turns the LCD off
// ON - Turns the LCD on
void glcd_init(int1 mode)
{
// Initialze some pins
output_high(GLCD_RST);
output_high(GLCD_CS);
output_high(GLCD_RD);
output_high(GLCD_WR);
glcd_systemSetup();
glcd_scrollSetup();
glcd_overlaySetup();
glcd_power(OFF);
glcd_cursorForm(4, 6);
glcd_fillScreen(OFF);
glcd_fillScreenText(' ');
glcd_power(mode);
glcd_cursorDirection(GLCD_CMD_CSRDIR_RIGHT);
}
// Purpose: Turn a pixel on a graphic LCD on or off
// Inputs: x - the x coordinate of the pixel
// y - the y coordinate of the pixel
// color - ON or OFF
void glcd_pixel(int16 x, int16 y, int1 color)
{
int8 data;
int16 addr;
// Calculate the byte address containing the pixel
addr = GLCD_GRAPHICS_ADDR + (GLCD_WIDTH/8 * y + x/8);
// Read the byte of data at the address
data = getData(addr);
// Turn the pixel on or off
if(color == ON)
bit_set(data, 7 - x%8);
else
bit_clear(data, 7 - x%8);
// Write the new data byte to display memory
setData(addr, data);
}
// Purpose: Initialize the display environment
void glcd_systemSetup()
{
output_low(GLCD_CS);
glcd_contrast(2);
glcd_sendCMD(GLCD_CMD_SYSTEM); // Setup the system
set_data(); // Set for data
glcd_sendByte(0x30); // No offset
glcd_sendByte(0x7F + GLCD_CHAR_WIDTH); // Set character width
glcd_sendByte(GLCD_CHAR_HEIGHT - 1); // Set character height
glcd_sendByte(GLCD_CR); // Display line address range
glcd_sendByte(0x2F); // TC/R
glcd_sendByte(GLCD_HEIGHT - 1); // Number of lines per frame
glcd_sendByte(GLCD_CR + 1); // Horizontal address range LSB (APL)
glcd_sendByte((GLCD_CR + 1) / 0xFF); // Horizontal address range MSB (APH)
}
// Purpose: Set the scroll start address and
// the size of a scroll block
void glcd_scrollSetup()
{
// Currently setup for a text and graphics layer
glcd_sendCMD(GLCD_CMD_SCROLL); // Setup scrolling
set_data(); // Set for data
glcd_sendByte(GLCD_TEXT_ADDR); // SAD1L
glcd_sendByte(GLCD_TEXT_ADDR / 0xFF); // SAD1H
glcd_sendByte(GLCD_HEIGHT - 1); // SL1
glcd_sendByte(GLCD_GRAPHICS_ADDR); // SAD2L
glcd_sendByte(GLCD_GRAPHICS_ADDR / 0xFF); // SAD2H
glcd_sendByte(GLCD_HEIGHT - 1); // SL2
glcd_sendByte(0x00); // SAD3L
glcd_sendByte(0x00); // SAD3H
glcd_sendByte(0x00); // SAD4L
glcd_sendByte(0x00); // SAD4H
glcd_sendCMD(GLCD_CMD_HDOT_SCR); // Horizontal scroll rate
set_data(); // Set for data
glcd_sendByte(0x00); // Horizontal pixel shift is 0
}
// Purpose: Setup the overlay functionality for combining
// layers of text and graphics, or multiple
// graphics layers
void glcd_overlaySetup()
{
// Currently setup for a single graphics layer
glcd_sendCMD(GLCD_CMD_OVERLAY); // Text / graphic overlay mode
set_data(); // Set for data
glcd_sendByte(0x8); // Area 1 text, others graphics
// Text XOR Graphics
}
// Purpose: Turn the display on or off
// Inputs: ON to turn on or OFF to turn off
void glcd_power(int1 mode)
{
if(mode == ON)
{
glcd_sendCMD(GLCD_CMD_DISP_ON); // Turn the display on
}
else
{
glcd_sendCMD(GLCD_CMD_DISP_OFF); // Turn the display off
}
set_data(); // Set for data
glcd_sendByte(0x14);
}
// Purpose: Set the direction the cursor moves after
// writing to dispaly memory
// Inputs: Use one of the following to set the direction:
// GLCD_CMD_CSRDIR_RIGHT
// GLCD_CMD_CSRDIR_LEFT
// GLCD_CMD_CSRDIR_UP
// GLCD_CMD_CSRDIR_DOWN
void glcd_cursorDirection(int8 dir)
{
glcd_sendCMD(dir);
}
// Purpose: Set the size of the cursor
// Inputs: 1) The width in pixels - 1 Valid numbers: (0 - 15)
// 2) The height in pixels - 1 Valid numbers: (1 - 15)
void glcd_cursorForm(int8 width, int8 height)
{
glcd_sendCMD(GLCD_CMD_CSR_FORM); // Cursor form and size
set_data(); // Set for data
glcd_sendByte(width);
glcd_sendByte(0x80 + height);
}
// Purpose: Fill a graphics layer passed in color
// Works much faster than drawing a rectangle to fill the screen
// Inputs: ON - turn all the pixels on
// OFF - turn all the pixels off
void glcd_fillScreen(int1 color)
{
int16 i;
setCursorAddress(GLCD_GRAPHICS_ADDR);
glcd_sendCMD(GLCD_CMD_DISPLAY_WRITE);
set_data();
for(i = GLCD_GRAPHICS_ADDR; i < GLCD_GRAPHICS_ADDR_END; ++i)
{
glcd_sendByte(0xFF * color);
}
}
// Purpose: Fill a text layer with a the passed in character
// Works much faster than drawing a rectangle to fill the screen
// Inputs: ON - turn all the pixels on
// OFF - turn all the pixels off
void glcd_fillScreenText(char c)
{
int16 i;
setCursorAddress(GLCD_TEXT_ADDR);
glcd_sendCMD(GLCD_CMD_DISPLAY_WRITE);
set_data();
for(i = GLCD_TEXT_ADDR; i < GLCD_GRAPHICS_ADDR; ++i)
{
glcd_sendByte(c);
}
}
// Purpose: Get the status
// Outputs: The status in an 8 bit integer
int8 getStatus()
{
int8 status;
set_data();
output_low(GLCD_CS);
output_low(GLCD_RD);
// delay_us(1);
status = input_d();
output_high(GLCD_RD);
output_high(GLCD_CS);
return status;
}
// Purpose: Write a byte of data
// Inputs: The byte of data to write
void glcd_sendByte(byte data)
{
output_d((data));
output_low(GLCD_CS);
// delay_cycles(1);
output_low(GLCD_WR);
output_high(GLCD_WR);
output_high(GLCD_CS);
}
// Purpose: Read a byte of data
// Outputs: The byte of data
int8 glcd_readByte()
{
byte data;
set_tris_d(0xFF);
output_low(GLCD_CS);
//delay_cycles(1);
output_low(GLCD_RD);
//delay_cycles(2);
data = input_d();
output_high(GLCD_RD);
output_high(GLCD_CS);
return data;
}
// Purpose: Get the current address of the cursor
// Outputs: A 16 bit integer containing the cursor address
int16 getCursorAddress()
{
int16 addr;
glcd_sendCMD(GLCD_CMD_GET_CSR_ADDR);
set_command();
*(int8*)(&addr ) = glcd_readByte(); // Read low part
*((int8*)&addr + 1) = glcd_readByte(); // Read high part
return addr;
}
// Purpose: Set the cursor address
// Inputs: A 16 bit integer containing the new cursor address
void setCursorAddress(int16 addr)
{
glcd_sendCMD(GLCD_CMD_SET_CSR_ADDR);
set_data();
glcd_sendByte(*(int8*)(&addr ));
glcd_sendByte(*((int8*)&addr + 1));
}
// Purpose: Get a byte of data from the display at the address
// Inputs: A 16 bit integer containing the address
// Outputs: An 8 bit integer with the read data
int8 getData(int16 addr)
{
setCursorAddress(addr);
glcd_sendCMD(GLCD_CMD_DISPLAY_READ);
set_command();
return glcd_readByte();
}
// Purpose: Set a byte of display data at an address
// Inputs: 1) A 16 bit address
// 2) 8 bits worth
void setData(int16 addr, int8 data)
{
setCursorAddress(addr);
glcd_sendCMD(GLCD_CMD_DISPLAY_WRITE);
set_data();
glcd_sendByte(data);
}
// Purpose: Send an 8 bit command
// Inputs: The command to send
void glcd_sendCMD(int8 cmd)
{
set_command();
glcd_sendByte(cmd);
}
#endif
|
Last edited by dezso on Sun Mar 28, 2010 11:39 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 28, 2010 10:52 pm |
|
|
Quote: |
#include <18F448.h>
#fuses H4,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#pragma use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
|
What is your crystal or external oscillator frequency ? |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sun Mar 28, 2010 11:43 pm |
|
|
ok You got me on this one !
I just change it to see if the extra speed will help.
The code I compiled and shown on the video is using MPLAB config settings not the files config, 20MHz and running on 20MHz, not on 80MHz. |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sun Mar 28, 2010 11:47 pm |
|
|
The uTube video has some delay !?
Here is picture shows the uneven insensitivity of the word "Hello DDS"
|
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sun Mar 28, 2010 11:58 pm |
|
|
Currently I'm using 3 graphic layer, instead of the original.
Code: | void glcd_overlaySetup()
{
// Currently setup for all graphics layer
glcd_sendCMD(GLCD_CMD_OVERLAY); // Text / graphic overlay mode
set_data(); // Set for data
glcd_sendByte(0x8); // All graphics
} |
|
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Mon Mar 29, 2010 12:16 am |
|
|
Just quickly recompiled one of earlier ASM test version.
No flicker, and I have not using any busy checking function.
http://www.youtube.com/watch?v=OTwgQ5_spKA
Code: | ;******************************************************************************
SEND_D1335_Command:
Bsf CMD_PORT,DA0
Nop
;******************************************************************************
SEND_D1335_Command_DATA:
Movwf DATA_PORT
Nop
Bsf CMD_PORT,DRD
Bcf CMD_PORT,DCS
Bcf CMD_PORT,DWR
Nop
Bsf CMD_PORT,DWR
Bsf CMD_PORT,DCS
Return
;******************************************************************************
WRITE32: Bcf CMD_PORT,DA0
Call SEND_D1335_Command_DATA
Return
;******************************************************************************
READ_DATA: Movlw 0XFF
Banksel TRISD
Movwf TRISD
Banksel PORTD
Bsf CMD_PORT,DA0
Bsf CMD_PORT,DWR
Bcf CMD_PORT,DCS
Bcf CMD_PORT,DRD
nop
Movf PORTD,W
Movwf D1
nop
Bsf CMD_PORT,DRD
nop
Bsf CMD_PORT,DCS
Movlw 0X00
Banksel TRISD
Movwf TRISD
Banksel PORTD
Return
;****************************************************************************** |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 29, 2010 12:24 am |
|
|
Why post just a few routines from the ASM driver ?
If you say the ASM driver works and the CCS driver doesn't, then
do a side-by-side comparison of the ASM driver and the .LST file
from the CCS driver.
I assume you are testing these two drivers on the exact same board ?
The C driver has all this MAX749 code. Does the ASM driver have that ?
Make the most minimal possible program with both drivers, and also
try to call similar routines in each driver from the main program.
Then compare the behavior when they run, and compare the ASM
and .LST files.
You might also comment out the C source code in the CCS routines
and substitute #asm blocks with the ASM driver code instead.
In other words, get creative. Do anything required to trouble-shoot the
problem. |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Mon Mar 29, 2010 9:23 am |
|
|
The ccs version works, unless I want less than 1 fps screen update.
Its extremely hard to read CCS ASM, I'm thinking to replace the sed1335.c with my complete asm driver.
Will see how that works. |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Mon Mar 29, 2010 10:50 am |
|
|
I've seen the same problem on one of my old projects. Looks like you have a solution. If you can please share the ASM! |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Mon Mar 29, 2010 5:41 pm |
|
|
Got is working, or at least now I find the differences between my method and the CCS.
I'll upload a short video for now, and try to make a presentable code for everyone here.
http://www.youtube.com/watch?v=t15ziQJ7K18 |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Thu Apr 01, 2010 5:41 pm |
|
|
False alarm, its not perfect Grrrrrrr
I'm was reading this timing wrong or not.
The memory can be changed without effecting the display when D6 High ?
Also the rising edge need to be detected as well, otherwise the write could occurred a few ns before its start to read it again.
Cant figure out how long is the TC/R, my TC/R calculation based on the data sheet is: ((((osc/frame rate)/diplay heigh)/10)+10) = ((((12000000/70)/240)/10)+10) = dec 81 or 0x51. ?
My progress halted here, need some input.
|
|
|
|