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.

DLPC350 I2C Validation error

Other Parts Discussed in Thread: DLPC350

Hello,

I using the attatch code to run pattern control on DLPC350,and if i send 0x7d to validate the configuration, error happened, the status byte of the read is 0x00 or 0xff.

I can use usb and GUI to control the pattern display,so i think the hardware is ok.

I have met this proble about one week long, I hope someone can help me to fix it.

#ifndef WRITE
#define WRITE 0x00
#endif
#ifndef READ
#define READ	0x00
#endif
#define DLP_SLAVE_ADDR	0x1A

u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();
    for(i=0;i<8;i++ )
	{
        I2c_Scl( 0 ); 
        delay_us(DLTIME);
		I2c_Scl( 1 );
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(DLTIME); 
    }					 
    if (!ack)
        IIC_NAck();
    else
        IIC_Ack();
    return receive;
}
int I2C_Dlp_Read( u8 cmd, u8* data, u8 len )
{
	u8 at_len = 0;
	u8 at_sts = 0;
	u8 at_ret = 1;
	u8 at_retry = 0;
	char* at_ptr = data;
    IIC_Start( );  
	IIC_Send_Byte( (u8)((DLP_SLAVE_ADDR << 1) & 0xFE ) );
	IIC_Wait_Ack( );
    IIC_Send_Byte( cmd  & 0x7F );
	IIC_Wait_Ack( );

    IIC_Stop();
	delay_ms(100);

	IIC_Start( );  
	IIC_Send_Byte( (u8)((DLP_SLAVE_ADDR << 1) | 0x01 ) );
	IIC_Wait_Ack( );

	do
	{
		at_sts = IIC_Read_Byte( 1 );
		if( (at_sts == 0x01) ||( at_sts == 0x03 )||( at_retry > 20 ) ){
			break;
		}
		at_retry++;
		delay_ms(100);
	}while( 1 );

	if(( at_sts != 0x01 )||(at_retry > 20)){	//error happened
		*data = 0xff;
		at_ret = 0;
	}else{
		for( at_len = 0; at_len < len; at_len++ ){
			*at_ptr = IIC_Read_Byte( 1 );
			at_ptr++;
		}
	}
    IIC_Stop();
	delay_ms(10);
	return at_ret;
}

int DLP4500_PatternDisplayModeSetup( void )
{
	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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(regAdd,&writeBuf[0],1) < 0)
		return -1;
		
//	(b) Set mailbox offset. 0x1A32
//Reg[0x76] = 0x00 
	regAdd = (0x76 | WRITE);
	writeBuf[0] = 0x00; 
	if(I2C_Dlp_Write1(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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(regAdd,&writeBuf[0],1) < 0)
		return -1;

//	(b) Set mailbox offset. 0x1A32
//Reg[0x76] = 0x00 
	regAdd = (0x76 | WRITE);
	writeBuf[0] = 0x00; 
	if(I2C_Dlp_Write1(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(I2C_Dlp_Write1(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(I2C_Dlp_Write1(regAdd,&writeBuf[0],1) < 0)
		return -1;

	delay_ms(500);
//Reg[0x7D] = 0x00 
	regAdd = (0x7D | WRITE);
	writeBuf[0] = 0x00; //Write dummy byte
	if(I2C_Dlp_Write1(regAdd,&writeBuf[0],1) < 0)
		return -1;
	delay_ms(5000);
//8. Execute the Validate command. 0x1A1A
//Reg[0x7D]
	regAdd = (0x7D | READ);
	if(I2C_Dlp_Read(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(I2C_Dlp_Read(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(I2C_Dlp_Read(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(I2C_Dlp_Read(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;	
}

void DlpCmdCtrl( char* rv_cmd )
{
	if( DLP4500_PatternDisplayModeSetup() == 0 ){
		dlp_PatternDisplay( 2 );	//start the pattern
		Debug("execok : OK");
	}else{
		Debug("execok : NG");
	}
}

  • The FW Version is 0.0.65534, is it too lod and not support I2C validation?
  • I update the FW3.0,the question is still happened.i can read the hardware status as 0x01, system status as 0x01, main status is 0xff.
    A imfo is if i set the clock delay from 100us to 10us,the write is ok,as I can change the video mode to pattern mode, but the read is failed,the status byte is always 0x00 or 0xff.If the delay back to 100us,the read is ok.
    Is there anyone can help to fixe this question?
  • Hi Jake,

    Thanks for your question. This is an issue that we are aware of and are currently working on evaluating how to fix. Once we have a recommendation on moving forward, we'll post back and provide some further guidance.

    Thank you,

    Paul

  • I found if I changed the wait ack time from 2.5ms to 60ms,it works. So think this is the reason.But I don't know what is the max of the ack time,Can you provide me a specific value. If the clock is 10us,the max ack time is? and if the clock is 100us,the max ack time is?
  • Hi Jake,

    We're still investigating so we don't really have this information on hand, sorry.

    Paul
  • Hi Paul,

    Is it that means there is not bug in my code,so you cann't reproduce any problem?

    BY the way, Something that confuse me.I write some code follow the Variable Exposure Video Steaming Pattern Mode Example(dlpu010e.pdf  P64,Table4-2), but the scence is looks like the image stores in flash,not the pictures output from the HDMI IF of PC.Can you tell me .The code is listed below.The same pattern I have test using the USB port,it is ok.

    Can you help me to check my code and tell me what's wrong.

    Thank you very much

        u8 temp[20];
        memset( temp, 0, 20 );
        //stop the sequence
        temp[0] = 0x00; //Stop Pattern sequence
        if( I2C_Dlp_Write1( 0x65,&temp[0],1) == 0)
            return -1;
        temp[0] = 0x01;            //1.set display to pattern mode
        if( I2C_Dlp_Write1( 0x69, temp, 1 ) == 0 )
            return -2;
        temp[0] = 0x00;            //2.set pattern display from video input source
        if( I2C_Dlp_Write1( 0x6F, temp, 1 ) == 0 )
            return -3;
        temp[0] = 0x04;            //3.set trigger mode for VSYNC triggered for variable expposure
        if( I2C_Dlp_Write1( 0x70, temp, 1 ) == 0 )
            return -4;
        temp[0] = 0x03;            //4.set pattern access for variable exposure
        if( I2C_Dlp_Write1( 0x77, temp, 1 ) == 0 )
            return -5;
        //5.set pattern difinition for the variable exposures.3 exposure patterns,3 patterns to dispaly.always repeat
        temp[0] = 0x02;
        temp[1] = 0x00;
        temp[2] = 0x02;
        temp[3] = 0x00;
        temp[4] = 0x00;
        temp[5] = 0x01;
        if( I2C_Dlp_Write1( 0x5B, temp, 6 ) == 0)
            return -6;
        //6.set offset pointer:initialize to 0
        temp[0] = 0x00;
        temp[1] = 0x00;
        if( I2C_Dlp_Write1( 0x5C, temp, 2 ) == 0)
            return -7;
        //7.Pattern data : external positive trigger,image index 0,Green led,8bit-depth,insert black,Buffer swap, exposure=10ms,priod=12ms
        temp[0] = 0x01;
        temp[1] = 0x28;
        temp[2] = 0x06;
        temp[3] = 0x00;
        temp[4] = 0x10;
        temp[5] = 0x27;
        temp[6] = 0x00;
        temp[7] = 0x00;
        temp[8] = 0xE0;
        temp[9] = 0x2E;
        temp[10] = 0x00;
        temp[11] = 0x00;
        if( I2C_Dlp_Write1( 0x5D, temp, 12 ) == 0)
            return -8;
        //8.Offset Pointer : increment by 1
        temp[0] = 0x01;
        temp[1] = 0x00;
        if( I2C_Dlp_Write1( 0x5C, temp, 2 ) == 0)
            return -9;
        //9.Pattern data : external positive trigger,image index 1,red led,8bit-depth,insert black,Buffer swap, exposure=10ms,priod=12ms
        temp[0] = 0x04;
        temp[1] = 0x18;
        temp[2] = 0x06;
        temp[3] = 0x00;
        temp[4] = 0x28;
        temp[5] = 0x30;
        temp[6] = 0x00;
        temp[7] = 0x00;
        temp[8] = 0x10;
        temp[9] = 0x27;
        temp[10] = 0x00;
        temp[11] = 0x00;
        if( I2C_Dlp_Write1( 0x5D, temp, 12 ) == 0)
            return -10;
        //10.Offset Pointer : increment by 1
        temp[0] = 0x02;
        temp[1] = 0x00;
        if( I2C_Dlp_Write1( 0x5C, temp, 2 ) == 0)
            return -11;
        //11.Pattern data : external positive trigger,image index 2,Blue led,8bit-depth,insert black,Buffer swap, exposure=9ms,priod=14ms
        temp[0] = 0x09;
        temp[1] = 0x48;
        temp[2] = 0x06;
        temp[3] = 0x00;
        temp[4] = 0xF8;
        temp[5] = 0x2A;
        temp[6] = 0x00;
        temp[7] = 0x00;
        temp[8] = 0xB0;
        temp[9] = 0x36;
        temp[10] = 0x00;
        temp[11] = 0x00;
        if( I2C_Dlp_Write1( 0x5D, temp, 12 ) == 0)
            return -12;
        //12.Close the mailbox access
        temp[0] = 0x00;
        if( I2C_Dlp_Write1( 0x77, temp, 1 ) == 0)
            return -13;
     

  • I will close it by myself.

    If the interval time between 2 write commands is 10ms, the error listed before happened.

    But if the interval changed to 100ms,not error happened.

    Maybe the write commands excutes too long, so users cannot  send the next command before it complete.

    How long is the interval wait time between commands to sure the last command is completed?

    Or, is there any method to check the last command completed ?