Friday, February 15, 2013

AKAI LTA-1SE302 - LTA-20E302 - LTA-20E303 - MX IC MX88L284-V - FLUSH FUNCTION - LINE WIRITE - LINE READ - GAMMA AND OTHER SOFTWARE DETAILS


SOFTWARE DETAILS
Serial bus interface uses the pin 185-183, AD[7]-AD[5] of MX88L284. In MX88L284, there is no pull high circuits in AD pads. AD[5] and AD[7] are the serial bus chip select and clock pins, they must be GLITCH FREE. Any redundant pulse of these two pins will make error, so when not accessing these two pins, they should be pulled high by outside circuits.
FLUSH FUNCTION
Flush function is a speedy way to fill memory with a specified color value.  There are 5 steps to use this function as following:
  1. Switch to still mode (Register 0x11h/bit 5=1)
  2. Setup the color to be filled. ( Register 0x9Bh~0x9Dh)
  3. Setup the line count to be filled. (Register 0x99h/0x9Ah, note that the define in this registers is different with they are used in line write function)
  4. Set the flush function( Register 0x9Eh/bit 3) and send a start command(Register 0x9Eh/bit 1 = 1)
  5. Wait the ready bit (Register 0x9Eh/bit0) set to 1. You can get the state by polling this bit directly or waiting for interrupt.
  6. Send a stop command.(Register 0x9Eh/bit 1 = 0)
Note that flush line length is fixed to 1024 pixels and the starting address is decided by reg. 0x96, 0x97, 0x98.
SAMPLE CODE
==================================================================
xdata unsigned char *io = (unsigned char xdata *)0xC000;
#define REGPORT(reg) ((*io)+reg)
#define CPUWRITEREADY() { while (!(REGPORT(0x9E) & 1)); }
void FlushColor(unsigned char color)
{
REGPORT(0x11) |= 0x20; /* switch to still mode */
REGPORT(0x9B) = colorR; /* setup flush color value */
REGPORT(0x9C) = colorG;
REGPORT(0x9D) = colorB;
/* set lines to write */
REGPORT(0x99) = 0x00;
REGPORT(0x9A) = 0x3;
REGPORT(0x9E) = 0x0A; /* start flush write */
CPUWRITEREADY();/* wait until flush finish */
REGPORT(0x9E) = 0; /* stop flush write */
}
============================================================
LINE WRITE
Line writes function is similar to flush function. If you like to write a pattern or a picture to memory, use the line write function.  Following steps show you the way to use line write function:
  1. Switch to still mode. (Register 0x11h/bit 5 = 1) This step prevent the input data destroy the image just written to memory.
  2. Set the displayed data format. (Register 0xCEh/bit 7. Bit 7 = 0 means the format is RGB 24 bit data, bit 7 = 1 and means the format is YUV422)
  3. Set the line width in pixels. (Register 0x99h, 9Ah)
  4. Set the written data format (Register 0xCEh/bit 5), write mode to line write (Register 0x9Eh/bit 3 = 0), R/W mode to write (Register 0x9Eh/bit 2 = 0).
  5. Tell the chip to start line write! (Register 0x9Eh/bit 1 = 1)
  6. Write one line data to data port (Register 0x9Fh). Assume there is N pixels in a line, you write N * 3 byte data in following sequence: R0, G0, B0, R1, G1, B1, … RN-1, GN-1, BN-1. If the data is in YUV422 format, the sequence in N * 2 bytes is as following: Y0, UV0, Y1, UV0, Y2, UV2, Y3, UV2, Y4, UV4, Y5, UV4, …,YN-2, UVN-2, YN-1, UVN-2.
  7. Wait ready signal. (Wait register 0x9Eh/bit 0 = 1)
  8. If there is another line’s data left, go to step 6 to write next line.
  9. When all lines are written, stop the line write function. (Register 0x9Eh/bit 1 = 0)
LINE WRITE FUNCTION: SAMPLE CODE
====================================================================
xdata unsigned char *io = (unsigned char xdata *)0xC000;
#define REGPORT(reg) ((*io)+reg)
#define CPUWRITEREADY() { while (!(REGPORT(0x9E) & 1)); }
void LineWriteRGB(void)
{
int i, j;
REGPORT(0x11) |= 0xE0; /* switch to force mode of still mode */
REGPORT(0xCE) &= ~0x80; /* set format to RGB */
/* set write length per scan line */
REGPORT(0x99) = 0; REGPORT(0x9A) = 4;
/* start CPU line write in RGB24 */
REGPORT(0x9E) = 0x02;
/* line write gray scale */
for (j=0; j<768; j++)
{
/* fill gray scale vertically */
for (i=0; i<1024; i++)
{
REGPORT(0x9F) = j; /* write red */
REGPORT(0x9F) = j; /* write green */
REGPORT(0x9F) = j; /* write blue */
}
CPUWRITEREADY(); /* wait until line write finish */
}
/* stop CPU line write */
REGPORT(0x9E) = 0x00;
}
================================================================
LINE READ
The following steps show the way to use line read function:
  1. Switch to still mode. (Register 0x11h/bit 5 = 1) This step prevents the input data from destroying the image to be read.
  2. Set the displayed data format. (Register 0xCEh/bit 7). Bit 7 = 0 means the format is RGB 24 bit data, bit 7 = 1 means the format is YUV422.
  3. Set the line width in pixel. (Register 0x99h, 9Ah).
  4. Set the read data format (Register 0xCEh/bit 5), R/W mode to read (Register 0x9Eh/bit 2 = 1).
  5. Tell the chip to start line write! (Register 0x9Eh/bit 1 = 1).
  6. Read one line data from data port (Register 0x9Fh). Assume there are N pixels in a line, you read N * 3 byte data in the following sequence: R0, G0, B0, R10, G1, B1, … RN-1, GN-1, BN-1. If the data is in YUV422 format, the sequence in N * 2 bytes is as following: Y0, U0V0, Y1, U0V0, Y2, U2V2, Y3, U2V2, Y4, U4V4, Y5, U4V4, …,YN-2, U N-2VN-2, YN-1, U N-2VN-2.
  7. Wait ready signal. (Wait register 0x9Eh/bit 0 = 1).
  8. IF there is another line to be read, go to step 6 to read next line.
  9. When all lines are read, stop the line read function. (Register 0x9Eh/bit 1 = 0)
LINE READ FUNCTION:  SAMPLE CODE
==================================================================
Xdata unsigned char *io = (unsigned char xdata *)0xC000;
Xdata unsigned char databuf[768][1024][3];
#define REGPORT(reg) ((*io)+reg)
#define CPUREADREADY( ) { while (!(REGPORT(0x9E) & 1);
void LineReadRGB(void)
{
int i, j;
REGPORT(0x11) | = 0x20; // switch to still mode
REGPORT(0xCE) & = ~0x80; // set format to RGB
REGPORT(0x99) = 0; REGPORT(0x9A) = 4; // set read length per scan line
REGPORT(0x9E) = 0x06; // start line read in RGB
for (j=0; j<768; j++)
{
CPUREADREADY( ); // wait until line read finish
for(i=0; i<1024; i++)
{
databuf[j][i][0] = REGPORT(0x9F); // read red
databuf[j][i][1] = REGPORT(0x9F); // read green
databuf[j][i] [2] = REGPORT(0x9F); // read blue
}
}
REGPORT(0x9E) = 0x04; // stop line read
}
=============================================================
GAMMA FUNCTION
There are 256 gamma entries in this chip. Following steps show the entries’ setup sequence:
  1. Reset the gamma I/O access. (Set register 0x3Dh/bit 3 to 0, bit 2 to 0)
  2. Set the gamma I/O accesses on. (Set register 0x3Dh/bit 3 to 1)
  3. Write gamma values (256 * 3 bytes) to register 0x4Ah. (Gamma table index 0 red color value, then index 0 green value, then index 0 blue value, then index 1 red value, index 1 green value, index 1 blue value, … to index 255 red value, index 255 green value, index 255 blue value.)
  4. Reset gamma I/O accesses again.
  5. To turn on the gamma function, just set register 0x3Dh/bit 3 to 1.
GAMMA FUNCTION:  SAMPLE CODE
===================================================================
xdata unsigned char *io = (unsigned char xdata *)0xC000;
#define REGPORT(reg) ((*io)+reg)
void SetupGammaTable(void)
{
unsigned char val;
REGPORT(0x3D) &= ~0x18; /* reset Gamma I/O */
REGPORT(0x3D) |= 0x10; /* enable Gamma I/O */
/* fill Gamma table */
for (i=0; i<256; i++)
{
val = power((i/255.0),(1/2.2))*255.0;
REGPORT(0x4A) = val; /* fill Gamma red */
REGPORT(0x4A) = val; /* fill Gamma green */
REGPORT(0x4A) = val; /* fill Gamma blue */
}
REGPORT(0x3D) &= ~0x18; /* reset Gamma I/O */
REGPORT(0x3D) |= 0x08; /* turn on Gamma function */
}
============================================================
PROCEDURE OF MEMORY CLOCK AND OUTPUT DOT CLOCK PROGRAMMING
============================================================
  1. Power On.
  2. Program MN register -- 0xB0 and 0xB1 for output dot clock 0xB2 and 0xB3 for memory clock
  3. Load Register Value by 0xB4 D1=1 for output dot clock 0xB4 D0=1 for memory clock
  4. Power down enable 0xB1 D6=1 for output dot clock 0xB3 D6=1 for memory clock
  5. Wait for over 1ms
  6. Power down disable 0xB1 D6=0 for output dot clock 0xB3 D6=0 for memory clock
  7. Resume clock load 0xB4 D1=0 for output dot clock 0xB4 D0=0 for memory clock.
INITIALIZE MIU
  • Waiting for procedure 1 ready. That means memory clock is generated.
  • Initialize MIU by programming 0x90 read 0x90 D7 if D7=0 then program D7=1 else if D7=1 program D7=0, then program D7=1
  • Reset MIU set 0xCD D3=1 then set 0xCD D3=0
  • Reset chip set 0xCD D0=1 then set 0xCD D0=0
MEMORY CLOCK CALCULATION
  • Memory clock = clock when R=00 = clock/2 when R=01 or 10 = clock/4 when R=11 clock = FREF * [(M+1)/(N+1)]
  • FREF is the external x'tal frequency, it use 14.318MHz in Macronix’s demo system.
  • Limitation to avoid jitter: FIN>2.0 MHz, FIN=FREF/(N+1) and 100MHz<FVCO<400MHz , FVCO=clock* 2.
  • To program this value, you have to set the M, N, and R in register 0xB2 and 0xB3.  Then toggle the bit0 of OxB4 (0 -> 1 ->0) to trigger the internal VCG to generate the new frequency after this setting.
OUTPUT VIDEO CLOCK CALCULATION
  • Output video clock = clock when R=00 = clock/2 when R=01 or 10 = clock/4 when R=11 clock = FREF * 2 * [(M+1)/(N+1)]
  • FREF is the external x'tal frequency, it use 14.318MHz in Macronix’s demo system.
  • Limitation to avoid jitter: FIN>2.0 MHz, FIN=FREF/(N+1) and 100MHz<FVCO<400MHz , FVCO=clock* BD*2.
BD=4 when B = 00
BD=2 when B = 01
BD=1 when B = 10
BD=1 when B = 11
  • To program these values, you have to set the M,N, R, and B in register 0xB0 and 0xB1.  Then toggle the bit1 of 0xB4 (0 -> 1 ->0) to trigger the internal VCG to generate the new frequency after this setting.
PROCEDURE OF AUTO-TRACKING
  1. Auto tracking is used to detect the input image dot clock rate and phase for programming of external PLL.  Support single/burst mode for your application. Optional mask bit is added to reduce the system noise from ADC.
  2. set Freq and Phase parameter for first frame
  3. set 0x87 D0 = 1 , Enable Tracking any time you wish
  4. check 0x87 D1 until = 1 , Tracking result ready
  5. read tracking value 0x8C - 0x88
  6. tune Phase or Freq for next frame . Be sure that the parameter set by CPU must ready before next frame display start. If not, incorrect input image may affect the tracking result.
  7. Freq and Phase parameter active to PLL must after ready bit 0x87 D1 = 1 and before next frame display area reach. Because you have almost 1 input frame time to read register 0x8C - 0x88, you can reorder procedure4/5 to match the requirement.
  8. repeat 3-5
  9. set 0x87 D0 = 0 , Tracking done! 
  10. The correct clock and phase has maximum tracking value.
All CPU reading command must be finished between two adjacent ready pulse. If not, new tracking result will be loaded when next ready pulse presented. If the reading command too long for your CPU, you can reduce the input vertical auto tracking range 0x79~0x7C to enlarge the tracking result ready time.
  • Before auto tracking , you should do auto position first to make sure that the sample range cover image source.
  • Set auto tracking horizontal range(0x75~0x78) to both 10 points of left and right side greater than horizontal image sample range.
  • Make sure that vertical range is corrected by programming the register 0x79~0x7C.
  • Enable the auto tracking range definition in suggestion 2 and 3 by programming the register 0x74 D1.
  • Set register 0x11 D0=1.
TIME SLOT OF AUTO TRACKING PROCEDURE
Time ->
| FP | VS | BP | DISP | FP | VS | BP | DISP |
|- ready bit -| |- ready bit -|
|- Next frame PLL parameter-| |- Next frame PLL parameter -|
|-- read tracking result registers --|-- read tracking result registers --|
FP : Front Porch
BP : Back Porch
VS : Vsync
Procedure of single mode Auto Tracking is (0x87 D2=1)
  1. set Freq and Phase parameter for first frame
  2. set 0x87 D0 = 1 , start tracking any time you wish
  3. check 0x87 D0 until = 0 , tracking done
  4. read tracking value 0x8C - 0x88, the tracking value will be hold until your next auto tracking done.
  5. tune Phase or Freq for next frame .
  6. repeat 2-5 until you finish your frequency and phase loop
  7. The correct clock and phase has maximum tracking value.
PROCEDURE OF DRAM SELF-TEST
  1. set 0x93 D2=1,self-testing mode
  2. flush write with flush color register 0x9A, 0x9B, 0x9C and cover all memory location
  3. wait flush finish
  4. modify display area to fit memory size which you want to test
  5. set 0x93 D0=1 self-testing start
  6. read 0x93 D0 until D0=0 stop
  7. read 0x93 D1= 1: test fail 0: test pass
  8. 0x93 D2=0 normal mode.
Flush Color (FC) fill DRAM in DRAM self-testing mode is md[47:0] = { Flush Color Red, Flush Color Green, Flush Color Blue, Flush Color Red, Flush Color Green, Flush Color Blue}
Suggestion : for toggle DRAM reason, you can repeat the procedure and a complement flush color is applied
Ex. Loop1: Flush Color(0x9A,9B,9C) = 55h, AAh, CCh then md[47:0] = 55AACC 55AACC h Loop2: Flush Color(0x9A,9B,9C) = AAh, 55h, 33h then md[47:0] = AA5533 AA5533 h
If the result of loop1, loop2 are all pass, then the memory interface of MX88L284 is fine.
HOW TO USE EDGE FILTER
Function : Programmable edge filter when 0x4F D7=1 should work with register
0x5A Coef-A
0x5B Coef-B
0x5C Coef-C
Function = (Next_pixel) * Coef-A + (Current_pixel) * Coef-B + (Previous_pixel) * Coef-C
1. sharpen (high pass filter)
meet:
Coef-A + Coef-B + Coef-C = 1
Coef-A, Coef-C < 0
2. blur (low pass filter)
meet:
Coef-A + Coef-B + Coef-C = 1
Coef-A, Coef-C > 0
3. Misc
no limitation, result depend on Coef-A/Coef-B/Coef-C
Example:  Coef-A/Coef-C (0x5A / 0x5C)
=================================
D7    D6   D5   D4   D3   D2   D1   D0
X .     X     X     X     X     X     X     X
| | |
Sign Fraction
0.125 (D) 0 .0 0 1 0 0 0 0 = 10 (H)
0.5 (D) 0 . 1 0 0 0 0 0 0 = 40 (H)
-0.5 (D) 1 . 1 0 0 0 0 0 0 = C0 (H)
(2'complement of 0.5) = inverse (40) + 1
Decimal meaning
  1. positive value = D7 + 1/2 * D6 + 1/4 * D5 + 1/8 * D4 + 1/16 * D3 + 1/32 * D2 + 1/64 * D1 + 1/128 * D0
  2. negative value  B[7:0] = ~D[7:0] + 1 = - (D7 + 1/2 * D6 + 1/4 * D5 + 1/8 * D4 + 1/16 * D3+ 1/32 * D2 + 1/64 * D1 + 1/128 * D0)
Ex. 40H = ~(C0) + 1  value = - ( 0 + 1/2 * 1 + 1/4 * 0 + 1/8 *0 + 1/16 *0 + 1/32 * 0 + 1/64 * 0 + 1/128 *0 ) = - 0.5