This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

control lc4500 with i2c to change mode

Other Parts Discussed in Thread: DLPC350

Hi,

I was trying to control  LC4500 in both the Pattern Sequence and  Video mode using I2C command.

One thing I found is:

First, I settle all the pattern sequence in the pattern mode, and display the patterns using the GUI version 1.2

Then, i change to the video mode using I2C command.

Then, I change back to the pattern sequence mode using I2C command.  Although the pattern sequences are still there (bottom left on GUI version 1.2), I still need to click the "Send" again to display all the pattern.

I am wondering which I2C command(s) I should use to resend all the sequence to dlpc350 instead of clicking the "send" button.

I want to control the dlpc350 to shift between these two modes only using I2C commands instead of the GUI.

Thanks,

Shang

  • Hello Shang,

    In the GUI code if you look at the "Send" button basically it setup the pattern sequence configuration. 

    Have wrote a small sample code showing the list of I2C commands to setup the pattern display mode configuration. You need to implement the commands in this order to display the pattern sequence mode.

    Regards,

    Sanjeev

    /*
    *	DLP4500: Pattern Display Mode & configuration sample code using i2c registers
    *	Sanjeev Kumar (malde@ti.com)
    *   Date: 20May2014
    */
    
    
    int DLP4500_StartPatternSequence()
    {
    
    	if(DLP4500_PatternDisplayModeSetup() == 0) 
    	{
    	//Assuming all the setup is correct 
    	//11. Start the pattern sequence, either with trig in2 or 0x1A24.
    	//Reg[0x65] = 0x00 //stop the sequence
    		regAdd = (0x65 | WRITE);
    		writeBuf[0] = 0x02; //Start Pattern sequence
    		if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    			return -1;
    	}
    	else
    	{
    		return -1;
    	}
    	
    	return 0;
    }
    
    int DLP4500_PatternDisplayModeSetup()
    {
    	unsigned char writeBuf[256];
    	unsigned char regAdd;
    	unsigned char numBytes;
    
    //1. Enable pattern display mode (bypass video processing algorithms) 0x1A1B -> 0x01.
    //Reg[0x69] = 0x01
    	regAdd = (0x69 | WRITE);
    	writeBuf[0] = 0x01;
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    	
    //2. Set pattern display mode to flash image or external video. 0x1A22 -> 0x03 or 0x00.
    //Reg[0x6F] = 0x00 or 0x03;
    	regAdd = (0x6F | WRITE);
    	writeBuf[0] = 0x03; //From the flash
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    
    //3. Ensure Pattern Sequence is stopped		
    //Reg[0x65] = 0x00 //stop the sequence
    	regAdd = (0x65 | WRITE);
    	writeBuf[0] = 0x00; //Stop Pattern sequence
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    		
    //3.1 Set the number of patterns. 0x1A31
    //	(a) Byte 0- number of LUT entries
    //	(b) Byte 1- setting 0x00 means the pattern sequence will be executed once; setting x01 means the pattern sequence will be repeated
    //	(c) Byte 2- determines the number of patterns in the pattern sequence (how many patterns between trigger out2 pulses)
    //	(d) Byte 3- if pattern display mode (Step 2) is set to flash images, this indicates the number of flash images used as patterns
    //Reg[0x75] = BYTE3 - BYTE0
    	//Example: Let's say there are 4 8-bit patterns to be displayed from two 24bit images from the flash
    	
    	regAdd = (0x75 | WRITE);
    	writeBuf[0] = 0x03; //4 8-bit patterns
    	writeBuf[1] = 0x01; //Patterns repeat 
    	writeBuf[2] = 0x03; //Number of patterns between trigger out2 pulses
    	writeBuf[3] = 0x01; //Two splash images used
    	if(WriteDlp(regAdd,&writeBuf[0],4) < 0)
    		return -1;	
    
    //4. Set the pattern trigger mode. 0x1A23 -> 0x00, 0x01, or 0x02 for mode 0, 1, or 2
    //Reg[0x70] = 0x02 //External trigger signal
    	regAdd = (0x70 | WRITE);
    	writeBuf[0] = 0x01; //Use Internal trigger
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    
    //5. Set the exposure and frame rate (4 bytes for each). 0x1A29
    //Reg[0x66] = BYTES[7-0]
    
    	regAdd = (0x66 | WRITE);
    	
    	//ExposureTime = 9000us (in hex 0x2328)
    	//FramePeriod =  10000us (in hex 0x2710)
    	
    	writeBuf[0] = 0x00; //Exposure time LSB + 3
    	writeBuf[1] = 0x00; //Exposure time LSB + 2
    	writeBuf[2] = 0x23; //Exposure time LSB + 1
    	writeBuf[3] = 0x28; //Exposure time LSB
    	
    	writeBuf[4] = 0x00; //Frame time LSB + 3
    	writeBuf[5] = 0x00; //Frame time LSB + 2
    	writeBuf[6] = 0x27; //Frame time LSB + 1
    	writeBuf[7] = 0x10; //Frame time LSB
    
    	if(WriteDlp(regAdd,&writeBuf[0],8) < 0)
    		return -1;
    
    //6. Set up the image indexes if using flash images.
    //	(a) Open mailbox. 0x1A33 -> 0x01 for image indexes
    //Reg[0x77] = 0x01 
    	regAdd = (0x77 | WRITE);
    	writeBuf[0] = 0x01; //Open mailbox for image indexes
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    		
    //	(b) Set mailbox offset. 0x1A32
    //Reg[0x76] = 0x00 
    	regAdd = (0x76 | WRITE);
    	writeBuf[0] = 0x00; 
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    
    //	(c) Set image indexes. 0x1A34
    //		(i) Choosing 1 or 2 image indexes
    //Reg[0x78] = BYTE_0, BYTE_1, ... BYTE_N 
    	regAdd = (0x78 | WRITE);
    	writeBuf[0] = 0x01; //Splash - 1
    	writeBuf[1] = 0x02;	//splash - 2 
    	if(WriteDlp(regAdd,&writeBuf[0],2) < 0)
    		return -1;
    
    //	(d) Close mailbox. 0x1A33 -> 0x00
    //Reg[0x77] = 0x00 
    	regAdd = (0x77 | WRITE);
    	writeBuf[0] = 0x00; //Close the mailbox
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    
    //7. Set up the LUT.
    //	(a) Open mailbox. 0x1A33 -> 0x02 for LUT
    //Reg[0x77] = 0x02 
    	regAdd = (0x77 | WRITE);
    	writeBuf[0] = 0x02; //Open mailbox for Pat LUT
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    
    //	(b) Set mailbox offset. 0x1A32
    //Reg[0x76] = 0x00 
    	regAdd = (0x76 | WRITE);
    	writeBuf[0] = 0x00; 
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    
    //	(c) Fill pattern data. 0x1A34
    //		(i) Byte 0, b1:0- choose trigger: internal (0x00), external positive (0x01), external negative (0x02),
    //		continue from previous (0x03)
    //		(ii) Byte 0, b7:2- choose pattern number (what bit planes will be illuminated). Max is 24 for 1 bitdepth
    //		(iii) Byte 1, b3:0, choose bit weight (1-8)
    //		(iv) Byte 1, b6:4, choose which LEDs are on (Blue, Green, Red)
    //		(v) Byte 2
    //			(i) b0- invert pattern if 1
    //			(ii) b1- insert black pattern after current pattern if 1 (should be 0 if continuous trigger)
    //			(iii) b2- perform buffer swap if 1
    //			(iv) b3- trigger out1 stays high (if this stays high for n patterns, then exposure time is shared
    //				between n patterns)
    //		(vi) Repeat (I) through (v) for each pattern in the sequence
    //Reg[0x78] = BYTE_0, BYTE_1, ... BYTE_N 
    	regAdd = (0x78 | WRITE);
    
    //Patter#1 - BYTE0 - B7:2 - 0x00 B1:0 - 0x01 = (0x00<<2|0x00) = 0x01
    //			 BYTE1 - B7:4 - 0x07 B3:0 - 0x08 = (0x07<<4|0x08) = 0x78
    //			 BYTE2 - B7:4 - 0x00 (RSVD) B3 - '0' B2 - '1' B1 - 	'1' B0 - '0' = 0x06
    	writeBuf[0] = 0x00;
    	writeBuf[1] = 0x78;
    	writeBuf[2] = 0x06;
    
    	
    //Patter#2 - BYTE0 - B7:2 - 0x01 B1:0 - 0x01 = (0x01<<2|0x00) = 0x04
    //			 BYTE1 - B7:4 - 0x07 B3:0 - 0x08 = (0x07<<4|0x08) = 0x78
    //			 BYTE2 - B7:4 - 0x00 (RSVD) B3 - '0' B2 - '0' B1 - 	'1' B0 - '0' = 0x02
    	writeBuf[3] = 0x04;
    	writeBuf[4] = 0x78;
    	writeBuf[5] = 0x02;
    
    //Patter#3 - BYTE0 - B7:2 - 0x02 B1:0 - 0x03 = (0x02<<2|0x00) = 0x08
    //			 BYTE1 - B7:4 - 0x07 B3:0 - 0x08 = (0x07<<4|0x08) = 0x78
    //			 BYTE2 - B7:4 - 0x00 (RSVD) B3 - '0' B2 - '0' B1 - 	'1' B0 - '0' = 0x02
    	writeBuf[6] = 0x08;
    	writeBuf[7] = 0x78;
    	writeBuf[8] = 0x02;
    
    //Patter#4 - BYTE0 - B7:2 - 0x00 B1:0 - 0x01 = (0x00<<2|0x01) = 0x01
    //			 BYTE1 - B7:4 - 0x07 B3:0 - 0x08 = (0x07<<4|0x08) = 0x78
    //			 BYTE2 - B7:4 - 0x00 (RSVD) B3 - '0' B2 - '1' B1 - 	'1' B0 - '0' = 0x06
    	writeBuf[9] = 0x00;
    	writeBuf[10] = 0x78;
    	writeBuf[11] = 0x06;
    
    	if(WriteDlp(regAdd,&writeBuf[0],12) < 0)
    		return -1;
    
    //	(d) Close mailbox. 0x1A33 -> 0x00
    //Reg[0x77] = 0x00 
    	regAdd = (0x77 | WRITE);
    	writeBuf[0] = 0x00; //Close the mailbox
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    
    //Reg[0x7D] = 0x00 
    	regAdd = (0x7D | WRITE);
    	writeBuf[0] = 0x00; //Write dummy byte
    	if(WriteDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    		
    //8. Execute the Validate command. 0x1A1A
    //Reg[0x7D]
    	regAdd = (0x7D | READ);
    	if(ReadDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    	
    	//Any flag set in the 0x7D return data shows wrong configuration
    	if(writeBuf[0] > 0x00)
    		return -1;
    
    //9. Read statuses. 0x1A0A, 0x1A0B, 0x1A0C
    //Reg[0x20] //Hardware status
    	regAdd = (0x20 | READ);
    	if(ReadDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    	
    	//Hardware status showing error
    	if(writeBuf[0] > 0x00)
    		return -1;
    
    //Reg[0x21] //Memory test status
    	regAdd = (0x21 | READ);
    	if(ReadDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    	
    	//Hardware status showing error
    	if(writeBuf[0] > 0x00)
    		return -1;
    
    //Reg[0x22] //Main status
    	regAdd = (0x22 | READ);
    	if(ReadDlp(regAdd,&writeBuf[0],1) < 0)
    		return -1;
    	
    	//Hardware status showing error
    	if(writeBuf[0] > 0x00)
    		return -1;
    
    //10. If the Validate or Status commands show an error, change the system configuration to remove the error.
    
    	return 0;	
    }
    
    int WriteDlp(U8 bAddr, U8 *pbData, U8 bWrCnt)
    {
    	//i2c driver code to send the data
    
    }
    
    int ReadDlp(U8 bAddr, U8 *pbData, U8 bRdCnt)
    {
    	//i2c driver codxe to read back the data
    }
    

  • Many thanks Sanjeev.

    This is really helpful.

    Shang

  • Hi Sanjeev,

    Thanks for the code. 

    I was trying to configure my dlpc350 as the example in the user guide (page 29) through i2c.

    I did follow your code to program my avr and also compared my code with the source code of the gui.

    I also check the saved solution from the gui for that example and tried to use its configuration data in my code.

    Sadly I failed to configure the pattern display and can't show the sequence as expected.

    Another weird thing is before running the configuration part, I can easily toggle the mode by send "m" through serial comm to the avr. After the configuration (send 't' to the avr), I can't even read the hardware status. The code gets stuck when it tried to read the ack from dlpc350 (line 693 in main.c), which should be 0x01.

    I tried to log everything, so there are lots of serial output code in it.

    Please check my code if you got time and let me know if you find any problems. 

    Three files are attached:

    1. main.c is the main file

    /*
     * runAvrOnArduino.c
     *
     * Created: 5/14/2014 5:46:09 PM
     *  Author: ms
     */ 
    
    
    
    /* define CPU frequency in Mhz here if not defined in Makefile */
    #ifndef F_CPU
    #define F_CPU 16000000UL
    #endif
    
    /* 9600 baud */
    #define UART_BAUD_RATE 9600
    #define ERROR 0
    #define SUCCESS (!ERROR)
    
    #include <stdlib.h>
    #include <avr/io.h>
    #include <string.h>     /* strcat */
    #include <stdlib.h>     /* strtol */
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    
    #include "uart.h"
    #include "twi.h"
    #include "dlpstatus.h"
    
    
    uint8_t DLPCReadByte(uint8_t readCommand, uint8_t bytesOfCommandData, uint8_t* readResult);
    uint8_t DLPWriteByte(uint8_t writeCommand, uint8_t bytesOfCommandData, uint8_t* writeData);
    
    int  DLPPatternDisplayModeSetup();
    
    
    const char *byte_to_binary(int x)
    {
    	static char b[9];
    	b[0] = '\0';
    
    	int z;
    	for (z = 128; z > 0; z >>= 1)
    	{
    		strcat(b, ((x & z) == z) ? "1" : "0");
    	}
    
    	return b;
    }
    
    
    int main(void)
    {
    	uint8_t u8ReadStatus;
    	uint8_t u8WriteStatus;
    	
    	uint8_t u8WriteBuffer[16];
    	
    	char getCommand;
    	
    	uint8_t displayModeReadResult;
    	uint8_t displayModeControlReadResult;
    	
        uart_init( UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU) );
        sei();
    	TWIInit();
    
    	_delay_ms(1000);
    			
        while(1)
        {
            //TODO:: Please write your application code 	
    		
    		getCommand = uart_getc();
    		
    		if (getCommand & UART_NO_DATA)
    		{
    		}
    		else 
    		{
    			if (getCommand == 'm')
    			{
    				uart_puts("read display mode");
    				u8ReadStatus = DLPCReadByte(displayModeRead, 1, &displayModeReadResult);
    				if (u8ReadStatus == SUCCESS)
    				{
    					uart_puts("Display mode: ");
    					uart_puts(byte_to_binary(displayModeReadResult));
    					uart_puts("\r\n");
    					
    					if (displayModeReadResult == 0x00)
    					{
    						u8WriteBuffer[0] = 0x01;
    						u8WriteStatus = DLPWriteByte(displayModeWrite, 1, &u8WriteBuffer[0]);
    						if (u8WriteStatus == SUCCESS)
    						{
    							uart_puts("Write display mode 0x01");
    							uart_puts("\r\n");
    						}
    					} else if (displayModeReadResult == 0x01)
    					{
    						u8WriteBuffer[0] = 0x00;
    						u8WriteStatus = DLPWriteByte(displayModeWrite, 1, &u8WriteBuffer[0]);
    						if (u8WriteStatus == SUCCESS)
    						{
    							uart_puts("Write display mode 0x00");
    							uart_puts("\r\n");
    						}
    					}	
    				} else {
    					uart_puts("Read Mode Error");
    					uart_puts("\r\n");
    				}
    				
    				uint8_t hardwareStatusReadResult;
    				u8ReadStatus = DLPCReadByte(hardwareStatusReadOnly, 1, &hardwareStatusReadResult);
    				if (u8ReadStatus == SUCCESS)
    				{
    					uart_puts("Hardware status: ");
    					uart_puts(byte_to_binary(hardwareStatusReadResult));
    					uart_puts("\r\n");
    				} else {
    					uart_puts("Read hardware status Error");
    					uart_puts("\r\n");
    				}
    				
    			} 
    			else if (getCommand == 'p')
    			{
    				uart_puts("read display mode");
    				uart_puts("\r\n");
    				u8ReadStatus = DLPCReadByte(displayModeRead, 1, &displayModeReadResult);
    				if (u8ReadStatus == SUCCESS)
    				{
    					if (displayModeReadResult == 0x01)
    					{
    						uart_puts("read display control");
    						u8ReadStatus = DLPCReadByte(displayModeControlRead, 1, &displayModeControlReadResult);
    						if (u8ReadStatus == SUCCESS)
    						{
    							uart_puts("Display mode control: ");
    							uart_puts(byte_to_binary(displayModeControlReadResult));
    							uart_puts("\r\n");
    							
    							if (displayModeControlReadResult == 0b00000010)
    							{
    								u8WriteBuffer[0] = 0b00000001;
    								u8WriteStatus = DLPWriteByte(displayModeControlWrite, 1, &u8WriteBuffer[0]);
    								if (u8WriteStatus == SUCCESS)
    								{
    									uart_puts("Write display control 0x01");
    									uart_puts("\r\n");
    								}
    							} 
    							else if (displayModeControlReadResult == 0b00000001)
    							{
    								u8WriteBuffer[0] = 0b00000010;
    								u8WriteStatus = DLPWriteByte(displayModeControlWrite, 1, &u8WriteBuffer[0]);
    								if (u8WriteStatus == SUCCESS)
    								{
    									uart_puts("Write display control 0x02");
    									uart_puts("\r\n");
    								}
    							}
    							else if (displayModeControlReadResult == 0b00000000)
    							{
    								u8WriteBuffer[0] = 0b00000010;
    								u8WriteStatus = DLPWriteByte(displayModeControlWrite, 1, &u8WriteBuffer[0]);
    								if (u8WriteStatus == SUCCESS)
    								{
    									uart_puts("Write display control 0x02");
    									uart_puts("\r\n");
    								}
    							}
    						} else {
    							uart_puts("Read Mode Control Error");
    							uart_puts("\r\n");
    						}
    					}
    				} else {
    				uart_puts("Read Mode Error");
    				uart_puts("\r\n");
    				}	
    								
    			} else if (getCommand == 's')
    			{
    				uart_puts("read display mode \r\n");
    				u8ReadStatus = DLPCReadByte(displayModeRead, 1, &displayModeReadResult);
    				if (u8ReadStatus == SUCCESS)
    				{
    					if (displayModeReadResult == 0x01)
    					{
    						uart_puts("read display control");
    						u8ReadStatus = DLPCReadByte(displayModeControlRead, 1, &displayModeControlReadResult);
    						if (u8ReadStatus == SUCCESS)
    						{
    							uart_puts("Display mode control: ");
    							uart_puts(byte_to_binary(displayModeControlReadResult));
    							uart_puts("\r\n");
    							
    							if (displayModeControlReadResult == 0b00000000)
    							{
    								u8WriteBuffer[0] = 0b00000010;
    								u8WriteStatus = DLPWriteByte(displayModeControlWrite, 1, &u8WriteBuffer[0]);
    								if (u8WriteStatus == SUCCESS)
    								{
    									uart_puts("Write display control 0x02");
    									uart_puts("\r\n");
    								}
    							}
    							else if (displayModeControlReadResult == 0b00000010)
    							{
    								u8WriteBuffer[0] = 0b00000000;
    								u8WriteStatus = DLPWriteByte(displayModeControlWrite, 1, &u8WriteBuffer[0]);
    								if (u8WriteStatus == SUCCESS)
    								{
    									uart_puts("Write display control 0x00");
    									uart_puts("\r\n");
    								}
    							}
    						}
    					}
    				}
    			} else if (getCommand == 't')
    			{
    				int result = DLPPatternDisplayModeSetup();
    				if (result == 0)
    				{
    					uart_puts("Pattern display mode setup SUCCESS");
    					uart_puts("\r\n");
    				}
    			}
    		}
        }
    }
    
    
    int  DLPPatternDisplayModeSetup()
    {
    	uint8_t u8ReadStatus;
    	uint8_t u8WriteStatus;
    	uint8_t u8WriteBuffer[100];
    	
    	// 1. Enable pattern display mode
    	u8WriteBuffer[0] = 0x01;
    	u8WriteStatus = DLPWriteByte(displayModeWrite, 1, &u8WriteBuffer[0]); // 0x69
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("enable pattern display");
    		uart_puts("1\r\n");
    	}
    		
    	// 2. Set pattern display mode to flash image or external video
    	u8WriteBuffer[0] = 0x03;
    	u8WriteStatus = DLPWriteByte(displayDataInputSourceWrite, 1, &u8WriteBuffer[0]); // 0x6F
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("Write data input source 0x03");
    		uart_puts("2\r\n");
    	}
    	
    
    	// 3.0. Ensure pattern sequence has been stopped
    	u8WriteBuffer[0] = 0x00;
    	u8WriteStatus = DLPWriteByte(displayModeControlWrite, 1, &u8WriteBuffer[0]); // 0x65
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("Stop the pattern sequence");
    		uart_puts("3\r\n");
    	}
    	
    	// 3.1. set the number of patterns
    	
    	u8WriteBuffer[0] = 0x17; // 0x17 = 23; value+1 as number of LUT entries
    	u8WriteBuffer[1] = 0x01; // pattern repeat
    	u8WriteBuffer[2] = 0x17; // 0x17 = 23; value+1 as number of patterns
    	u8WriteBuffer[3] = 0x00; // 0x00 = 0; value+1 as number of splash images used
    	
    	u8WriteStatus = DLPWriteByte(patternDisplayLUTControlWrite, 4, &u8WriteBuffer[0]); // 0x75
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("set the number of patterns");
    		uart_puts("3.1\r\n");
    	}
    	
    	
    	// 4. set the pattern trigger mode
    	u8WriteBuffer[0] = 0x01; // internal trigger
    	u8WriteStatus = DLPWriteByte(patternTriggerModeWrite, 1, &u8WriteBuffer[0]); // 0x70
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("set the pattern trigger mode");
    		uart_puts("4\r\n");
    	}
    	
    	// 5. set the exposure and frame rate (four bytes for each)
    	
    	// for 100000us
    	u8WriteBuffer[0] = 0x00; //Exposure time LSB + 3
    	u8WriteBuffer[1] = 0x01; //Exposure time LSB + 2
    	u8WriteBuffer[2] = 0x86; //Exposure time LSB + 1
    	u8WriteBuffer[3] = 0xA0; //Exposure time LSB
    	
    	// for 100000us
    	u8WriteBuffer[4] = 0x00; //Frame time LSB + 3
    	u8WriteBuffer[5] = 0x01; //Frame time LSB + 2
    	u8WriteBuffer[6] = 0x86; //Frame time LSB + 1
    	u8WriteBuffer[7] = 0xA0; //Frame time LSB
    	
    
    	u8WriteStatus = DLPWriteByte(patternExposureTimeAndFrameWrite, 8, &u8WriteBuffer[0]); // 0x66
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("set exposure and frame rate");
    		uart_puts("5\r\n");
    	}
    	
    	// 6. set up the image indexes for using flash images
    	
    	// 6.a. open the mailbox for image indexes configuration
    	u8WriteBuffer[0] = 0x01;
    	u8WriteStatus = DLPWriteByte(patternDisplayLUTAccessWriteOnly, 1, &u8WriteBuffer[0]); // 0x77
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("open the mailbox for image index");
    		uart_puts("6.a\r\n");
    	}
    	
    	// 6.b. set mailbox offset
    	u8WriteBuffer[0] = 0x00;
    	u8WriteStatus = DLPWriteByte(patternDisplayMailboxOffsetWriteOnly, 1, &u8WriteBuffer[0]); // 0x76
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("set the mailbox offset");
    		uart_puts("b\r\n");
    	}	
    	// 6.c. set image indexes
    	u8WriteBuffer[0] = 0x08;
    	u8WriteStatus = DLPWriteByte(patternDisplayImageIndexWriteOnly, 1, &u8WriteBuffer[0]); // 0x78
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("set image indexes");
    		uart_puts("c\r\n");
    	}	
    	// 6.d. close the mailbox
    	u8WriteBuffer[0] = 0x00;
    	u8WriteStatus = DLPWriteByte(patternDisplayLUTAccessWriteOnly, 1, &u8WriteBuffer[0]); // 0x77
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("close the mailbox for image index");
    		uart_puts("d\r\n");
    	}
    	
    	// 7. set up the LUT
    	// 7.a open mailbox for pattern definition 
    	u8WriteBuffer[0] = 0x02;
    	u8WriteStatus = DLPWriteByte(patternDisplayLUTAccessWriteOnly, 1, &u8WriteBuffer[0]); // 0x77
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("open the mailbox for pattern");
    		uart_puts("7.a\r\n");
    	}
    	// 7.b set mailbox offset // 0x76
    	u8WriteBuffer[0] = 0x00;
    	u8WriteStatus = DLPWriteByte(patternDisplayMailboxOffsetWriteOnly, 1, &u8WriteBuffer[0]); // 0x76
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("set the mailbox offset");
    		uart_puts("b\r\n");
    	}
    	
    	// 7.c fill pattern sequence data 
    	// (i) Byte 0, b1:0- choose trigger: internal (0x00), external positive (0x01), external negative (0x02),
    	//		continue from previous (0x03)
    	//	(ii) Byte 0, b7:2- choose pattern number (what bit planes will be illuminated). Max is 24 for 1 bitdepth
    	//	(iii) Byte 1, b3:0, choose bit weight (1-8)
    	//	(iv) Byte 1, b6:4, choose which LEDs are on (Blue, Green, Red)
    	//	(v) Byte 2
    	//		(i) b0- invert pattern if 1
    	//		(ii) b1- insert black pattern after current pattern if 1 (should be 0 if continuous trigger)
    	//		(iii) b2- perform buffer swap if 1
    	//		(iv) b3- trigger out1 stays high (if this stays high for n patterns, then exposure time is shared
    	//				between n patterns)
    	//	(vi) Repeat (I) through (v) for each pattern in the sequence
    	
    	// pattern 1
    	u8WriteBuffer[0] = 0x00;
    	u8WriteBuffer[1] = 0x21;
    	u8WriteBuffer[2] = 0x06;
    	// pattern 2
    	u8WriteBuffer[3] = 0x04;
    	u8WriteBuffer[4] = 0x21;
    	u8WriteBuffer[5] = 0x02;
    	// pattern 3
    	u8WriteBuffer[6] = 0x08;
    	u8WriteBuffer[7] = 0x21;
    	u8WriteBuffer[8] = 0x00;
    	// pattern 4
    	u8WriteBuffer[9] = 0x0c;
    	u8WriteBuffer[10] = 0x21;
    	u8WriteBuffer[11] = 0x00;
    	// pattern 5
    	u8WriteBuffer[12] = 0x10;
    	u8WriteBuffer[13] = 0x21;
    	u8WriteBuffer[14] = 0x00;
    	// pattern 6
    	u8WriteBuffer[15] = 0x14;
    	u8WriteBuffer[16] = 0x21;
    	u8WriteBuffer[17] = 0x00;
    	// pattern 7
    	u8WriteBuffer[18] = 0x18;
    	u8WriteBuffer[19] = 0x21;
    	u8WriteBuffer[20] = 0x00;
    	// pattern 8
    	u8WriteBuffer[21] = 0x1c;
    	u8WriteBuffer[22] = 0x21;
    	u8WriteBuffer[23] = 0x00;
    	// pattern 9
    	u8WriteBuffer[24] = 0x20;
    	u8WriteBuffer[25] = 0x21;
    	u8WriteBuffer[26] = 0x00;
    	// pattern 10
    	u8WriteBuffer[27] = 0x24;
    	u8WriteBuffer[28] = 0x21;
    	u8WriteBuffer[29] = 0x00;
    	// pattern 11
    	u8WriteBuffer[30] = 0x28;
    	u8WriteBuffer[31] = 0x21;
    	u8WriteBuffer[32] = 0x00;
    	// pattern 12
    	u8WriteBuffer[33] = 0x2c;
    	u8WriteBuffer[34] = 0x21;
    	u8WriteBuffer[35] = 0x00;
    	// pattern 13
    	u8WriteBuffer[36] = 0x30;
    	u8WriteBuffer[37] = 0x21;
    	u8WriteBuffer[38] = 0x00;
    	// pattern 14
    	u8WriteBuffer[39] = 0x34;
    	u8WriteBuffer[40] = 0x21;
    	u8WriteBuffer[41] = 0x00;
    	// pattern 15
    	u8WriteBuffer[42] = 0x38;
    	u8WriteBuffer[43] = 0x21;
    	u8WriteBuffer[44] = 0x00;
    	// pattern 16
    	u8WriteBuffer[45] = 0x3c;
    	u8WriteBuffer[46] = 0x21;
    	u8WriteBuffer[47] = 0x00;
    	// pattern 17
    	u8WriteBuffer[48] = 0x40;
    	u8WriteBuffer[49] = 0x21;
    	u8WriteBuffer[50] = 0x00;
    	// pattern 18
    	u8WriteBuffer[51] = 0x44;
    	u8WriteBuffer[52] = 0x21;
    	u8WriteBuffer[53] = 0x00;
    	// pattern 19
    	u8WriteBuffer[54] = 0x48;
    	u8WriteBuffer[55] = 0x21;
    	u8WriteBuffer[56] = 0x00;
    	// pattern 20
    	u8WriteBuffer[57] = 0x4c;
    	u8WriteBuffer[58] = 0x21;
    	u8WriteBuffer[59] = 0x00;
    	// pattern 21
    	u8WriteBuffer[60] = 0x50;
    	u8WriteBuffer[61] = 0x21;
    	u8WriteBuffer[62] = 0x00;
    	// pattern 22
    	u8WriteBuffer[63] = 0x54;
    	u8WriteBuffer[64] = 0x21;
    	u8WriteBuffer[65] = 0x00;
    	// pattern 23
    	u8WriteBuffer[66] = 0x58;
    	u8WriteBuffer[67] = 0x21;
    	u8WriteBuffer[68] = 0x02;
    	// pattern 24
    	u8WriteBuffer[69] = 0x5c;
    	u8WriteBuffer[70] = 0x21;
    	u8WriteBuffer[71] = 0x02;
    	
    	// 0x78
    	u8WriteStatus = DLPWriteByte(patternDisplayImageIndexWriteOnly, 72, &u8WriteBuffer[0]); // 0x78
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("fill pattern data");
    		uart_puts("c\r\n");
    	}	
    	// 7.d close mailbox
    	u8WriteBuffer[0] = 0x00;
    	u8WriteStatus = DLPWriteByte(patternDisplayLUTAccessWriteOnly, 1, &u8WriteBuffer[0]);  // 0x77
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("close the mailbox for pattern");
    		uart_puts("d\r\n");
    	}
    	// 7.e  write dummy data for validation
    	u8WriteBuffer[0] = 0x00;
    	u8WriteStatus = DLPWriteByte(patternDisplayValidationWrite, 1, &u8WriteBuffer[0]); // 0x7D
    	if (u8WriteStatus == SUCCESS)
    	{
    		//uart_puts("write dummy data for validation");
    		uart_puts("e\r\n");
    	}
    	
    	// 8. Execute the validation command
    	uint8_t validationReadResult;
    	u8ReadStatus = DLPCReadByte(patternDisplayValidationRead, 1, &validationReadResult); // 0x7D for read
    	if (u8ReadStatus == SUCCESS)
    	{
    		if (validationReadResult != 0x00)
    		{
    			return -1;
    		} else {
    			uart_puts("8");
    			uart_puts("\r\n");
    		}
    	}	
    	
    	
    	// 9. Read statuses
    	
    	uint8_t hardwareStatusReadResult;
    	u8ReadStatus = DLPCReadByte(hardwareStatusReadOnly, 1, &hardwareStatusReadResult); // 0x20
    	if (u8ReadStatus == SUCCESS)
    	{
    		uart_puts("Hardware status: ");
    		uart_puts(byte_to_binary(hardwareStatusReadResult));
    		uart_puts("\r\n");
    	}
    	uint8_t systemStatusReadResult;
    	u8ReadStatus = DLPCReadByte(systemStatusReadOnly, 1, &systemStatusReadResult); // 0x21
    	if (u8ReadStatus == SUCCESS)
    	{
    		uart_puts("System status: ");
    		uart_puts(byte_to_binary(systemStatusReadResult));
    		uart_puts("\r\n");
    	}
    	uint8_t mainStatusReadResult;
    	u8ReadStatus = DLPCReadByte(mainStatusReadOnly, 1, &mainStatusReadResult); // 0x22
    	if (u8ReadStatus == SUCCESS)
    	{
    		uart_puts("Main status: ");
    		uart_puts(byte_to_binary(mainStatusReadResult));
    		uart_puts("\r\n");
    	}
    	
    	
    	// 10. start display patterns
    	u8WriteBuffer[0] = 0x02;
    	u8WriteStatus = DLPWriteByte(displayModeControlWrite, 1, &u8WriteBuffer[0]); // 0x65
    	if (u8WriteStatus == SUCCESS)
    	{
    		uart_puts("10");
    		uart_puts("\r\n");
    	}
    	
    	
    	return 0;
    		
    }
    
    
    uint8_t DLPWriteByte(uint8_t writeCommand, uint8_t bytesOfCommandData, uint8_t*  writeData)
    {
    //	uart_puts("write will start \r\n");
    	
    	TWIStart();
    	if (TWIGetStatus() != 0x08)
    	{
    //		uart_puts("Can't start: ");
    //		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    //	uart_puts("write starts \r\n");
    	
    	TWIWrite(writeOnLow);
    	if (TWIGetStatus() != 0x18)
    	{
    //		uart_puts("Can't write: ");
    //		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    //	uart_puts("write address \r\n");
    	
    	TWIWrite(writeCommand);
    	if (TWIGetStatus() != 0x28)
    	{
    //		uart_puts("Can't write: ");
    //		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    	
    	
    	for (int i=0; i<bytesOfCommandData; i++)
    	{
    		TWIWrite(*writeData++);
    		if (TWIGetStatus() != 0x28)
    		{
    //			uart_puts("Can't write: ");
    //			uart_putc(TWIGetStatus());
    			return ERROR;
    		}
    	}
    	
    	/*
    	TWIWrite(writeData);	
    	*/
    	
    	TWIStop();
    //	uart_puts("write end \r\n");
    	return SUCCESS;
    	
    }
    
    uint8_t DLPCReadByte(uint8_t readCommand, uint8_t bytesOfCommandData, uint8_t * readResult)
    {
    	uart_puts("-- read will start \r\n");
    	
    	TWIStart();
    	if (TWIGetStatus() == 0x08)
    	{
    		uart_puts("---- read starts \r\n");
    	} else if (TWIGetStatus() == 0x10)
    	{
    		uart_puts("---- start again \r\n");	
    	} else
    	{
    		uart_puts("---- Can't start: ");
    		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    
    	
    	TWIWrite(writeOnLow);
    	if (TWIGetStatus() != 0x18)
    	{
    		uart_puts("---- Can't write: ");
    		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    	uart_puts("---- write address \r\n");
    	
    	TWIWrite(readCommand);
    	if (TWIGetStatus() != 0x28)
    	{
    		uart_puts("---- Can't write: ");
    		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    	uart_puts("---- write command \r\n");
    	
    	TWIStart();
    	if (TWIGetStatus() != 0x10)
    	{
    		uart_puts("---- Can't start: ");
    		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    	uart_puts("---- read starts again\r\n");
    	
    	TWIWrite(readOnLow);
    	if (TWIGetStatus() != 0x40)
    	{
    		uart_puts("---- Can't write: ");
    		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    	uart_puts("---- write readOnLow\r\n");
    	
    	uint8_t readStatus = TWIReadACK();
    	if (TWIGetStatus() != 0x50)
    	{
    		uart_puts("---- Can't read: ");
    		uart_putc(TWIGetStatus());
    		return ERROR;
    	}
    	uart_puts("---- get read status\r\n");
    	
    	while (!readStatus)
    	{
    		readStatus = TWIReadACK();
    	}
    	
    	if (readStatus == 0x01)
    	{
    		uart_puts("---- right status\r\n");
    	} else {
    		uart_puts("---- wrong status \r\n"); // shouldn't come into here
    	}
    	
    	for (int i=0; i<bytesOfCommandData; i++)
    	{
    		*readResult++ = TWIReadACK();
    		if (TWIGetStatus() != 0x50)
    		{
    			uart_puts("---- Can't read: ");
    			uart_putc(TWIGetStatus());
    			return ERROR;
    		}
    	}
    	
    	TWIStop();
    	uart_puts("-- read end \r\n");
    	return SUCCESS;
    }
    
    

    2. dlpstatus.h is where I keep all dlpc350 command7462.dlpstatus.h

    3. exampleSolution.ini is the saved solution from Gui for the example in the lc4500 user guide, page 29, which is also what I want to implement but using I2C.http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-components-files/924/2577.exampleSolution.ini

    Many thanks for your help.

    Shang

  • Hello Shang, 

    In your main.c line# 511. //8. Execute the validation command is it passing?

    To debug further, you can comment out /9. Read status instead put hard coded delay like 1000ms and then continue with step 10. Start display patterns. Let me know what happens.

    Let me know what happens,

    Regards,

    Sanjeev

  • Hi Sanjeev,

    Sorry for not making it clear.

    No, the code won't go through the validation (step 8) and the status reading (step 9). It got stuck at the line you mentioned, which is reading the validation byte.

    It seems that I can't do any reading from dlpc350 as long as the step 1 to 7 got executed. 

    I also tried to comment out both the step 8 and step 9 and add the delay (1000ms, 2000ms, or 3000ms). This lets me go through the code to step 10 (starting display) but  the lc4500 is displaying something I don't know. And still, I can't read anything from dlpc350 anymore.

    I am really grateful for your help. Let me know if you have any suggestions.

    Shang

  • Shang,

    In your code, Step#8 Execute Validation command is must without which the pattern mode will never configured successfully. Since you commented out #8 the result of starting the pattern sequence is unknown. So Validation is command is must.

    What do you mean by code won't go through Step #8? What error you are seeing? Provide us more details.

    If validation is failing you should determine what error it is by reading back register 0x7D Table 2-48 DLPC350 Programmer Guide.

    Regards,
    Sanjeev

     

  • Hi Sanjeev,

    Here is the details:

    The code won't go through step 8, because in step 8, we need to read a byte from 0x7D. 

    While reading a byte from dlpc350 through i2c, we first need write the command (0x7D in this case) to i2c bus and then we need read a status byte and checks that bit zero is set (step 4 at Page 6 of the programming guide for i2c reading). I put a " while loop" in the code, line 686, to make sure that 0x1 is return as the status. 

    The code got stuck here. When it tried to read a byte from 0x7D, it never get the right status (0x1). 

    Let me know if this is clear to you.

    Shang

  • Shang,

    Add delay after step 7.e and before step 8.

    Basically after you issue validate command i.e., Write into register 0x7D data = 0x00 //Dummy data, the controller takes some time to process the validation steps, looks at different parameters of the pattern display configuration, So before reading the status at line #511 put sufficient delay here like 1000ms and then check.

    Regards,
    Sanjeev

  • Sanjeev,

    Good news. It works. After adding the delay, the code can go through step 8 and 9.

    But still, the projector is not displaying the sequences I sent. 

    Here is the validation error I got from step 8 (0x7D): 00001000. I check the programming guide. It means "Warning, post vector was not inserted prior to external triggered vector".  

    I really have no idea what this means, since I use "internal trigger" for all the 24 sequences I sent.

    here is the 24 sequence, three bytes for each:

    0x62100 0x22104 0x2108 0x210c 0x2110 0x2114 0x2118 0x211c

    0x2120 0x2124 0x2128 0x212c 0x2130 0x2134 0x2138 0x213c

    0x2140 0x2144 0x2148 0x214c 0x2150 0x2154 0x22158 0x2215c ;

    The results from system and hardware status are fine. But the reading for main status is 00001100, indicating that Frame Buffer is frozen and Gamma Correction is enabled.

    Let me know your thoughts on this problem. Any suggestion would be highly appreciated.

    Shang

  • Hello Shang,

    About the 24 sequence, could you use the xls tool that is released with the GUI tool to validate your configuration again. To start with just try simple 1 or 2 pattern display, this will help you to isolate the problem if you are making some mistake in the pattern sequence LUT creation.

    Since the error is a 'warning' message are you seeing the patterns displayed now?

    Regards,

    Sanjeev