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.

DLPC-API: Multiple pattern set does not work

Part Number: DLPC-API
Other Parts Discussed in Thread: DLPC3478, TI-API

Hello TI,

I'm trying to run sample code in the "DLPC-API-1.10\samples".

For me, the projector controller device is DLPC3478, so I'm working with "dlpc347x_samples.c".

I succeeded running the sample code with "LoadFromFirmware" mode, but when I try a mode that generates patterns which starts with "PopulatePatternSetData(MAX_WIDTH, MAX_HEIGHT)",

I can only project the first pattern set although the four number of pattern sets are in the data structure. (Which TI offered originally)

What should I do?

Thank you

  • Hello Junyoung,

    Have you modified the function at all? How are you calling it and what are you seeing projected? Feel free to share any screenshots you can.

    Best,

    Maximus

  • Thank you for your kind reply

    I didn't change the function, and I'm using it like this:

    else
    	{
    		/* Prepare the data for pattern data block generation */
    		PopulatePatternSetData(MAX_WIDTH, MAX_HEIGHT);
    		PopulatePatternTableData();
    
    		/* Stop pattern display */
    		DLPC34XX_WriteInternalPatternControl(DLPC34XX_PC_STOP, 0);
    
    		/* Generate and program the pattern data to the controller flash */
    		GenerateAndProgramPatternData(DLPC34XX_INT_PAT_DMD_DLP3010, false, false);
    
    		/* Load Pattern Order Table Entry from Flash */
    		LoadPatternOrderTableEntryfromFlash();
    
    		/* Generate and write pattern data to a file */
    		GenerateAndWritePatternDataToFile(DLPC34XX_INT_PAT_DMD_DLP3010, (char*)"pattern_data.bin", false, false);
    	}
    
    	/* Display patterns */
    	DLPC34XX_WriteOperatingModeSelect(DLPC34XX_OM_SENS_INTERNAL_PATTERN);
    	DLPC34XX_WriteTriggerOutConfiguration(DLPC34XX_TT_TRIGGER1, DLPC34XX_TE_DISABLE, DLPC34XX_TI_NOT_INVERTED, 0);
    
    	DLPC34XX_WriteInternalPatternControl(DLPC34XX_PC_START, 0);
    	Sleep(10000);
    	DLPC34XX_WriteInternalPatternControl(DLPC34XX_PC_STOP, 0);
    
    	CYPRESS_I2C_RelinquishI2CBusAccess();

    I'm just copy and paste the original code and changed into cpp,

    but it's same with TI offered original code. (except the Sleep() function)

    Best regards,

    Junyoung

  • Hi Maximus,

    I'm keep trying to handle this problem and I got an additional problem.

    When writing pattern with below command,

    DLPC34XX_WriteInternalPatternControl(DLPC34XX_PC_START, 0);

    I changed the second argument 255, but the pattern does not repeat continuously.

    Please reply me how to handle this problem also with the original problem...

    Thank you,

    Junyoung

  • Hi Junyoung, 

    can you try the following lines:

    DLPC34XX_WriteOperatingModeSelect(0x04);
    DLPC34XX_WriteInternalPatternControl(0x00, 0xFF);
    can you also set up a logic analyzer to the I2C bus to monitor everything is being set properly and there are not any unwanted additional commands being set?
    Best,
    Maximus
  • Hi Maximus,

    Thank you for your kind reply.

    I don't know why it works, but the "Run Continuously" works fine when I try the same code after the weekend.

    But the "Multiple pattern set" problem still exists. (Only the first pattern set is projected while I wrote 2 pattern sets.)

    #define MAX_WIDTH                         DLP3010_WIDTH
    #define MAX_HEIGHT                        DLP3010_HEIGHT
    
    #define NUM_PATTERN_SETS                  2
    #define NUM_PATTERN_ORDER_TABLE_ENTRIES   2
    #define NUM_ONE_BIT_HORIZONTAL_PATTERNS   5
    #define NUM_EIGHT_BIT_HORIZONTAL_PATTERNS 0
    #define NUM_ONE_BIT_VERTICAL_PATTERNS     5
    #define NUM_EIGHT_BIT_VERTICAL_PATTERNS   0
    #define TOTAL_HORIZONTAL_PATTERNS         (NUM_ONE_BIT_HORIZONTAL_PATTERNS + NUM_EIGHT_BIT_HORIZONTAL_PATTERNS)
    #define TOTAL_VERTICAL_PATTERNS           (NUM_ONE_BIT_VERTICAL_PATTERNS + NUM_EIGHT_BIT_VERTICAL_PATTERNS)
    
    #define FLASH_WRITE_BLOCK_SIZE            1024
    #define FLASH_READ_BLOCK_SIZE             256
    
    #define MAX_WRITE_CMD_PAYLOAD             (FLASH_WRITE_BLOCK_SIZE + 8)
    #define MAX_READ_CMD_PAYLOAD              (FLASH_READ_BLOCK_SIZE  + 8)
    
    static uint8_t                                   s_HorizontalPatternData[TOTAL_HORIZONTAL_PATTERNS][MAX_HEIGHT];
    static uint8_t                                   s_VerticalPatternData[TOTAL_VERTICAL_PATTERNS][MAX_WIDTH];
    static DLPC34XX_INT_PAT_PatternData_s            s_Patterns[TOTAL_HORIZONTAL_PATTERNS + TOTAL_VERTICAL_PATTERNS];
    static DLPC34XX_INT_PAT_PatternSet_s             s_PatternSets[NUM_PATTERN_SETS];
    static DLPC34XX_INT_PAT_PatternOrderTableEntry_s s_PatternOrderTable[NUM_PATTERN_ORDER_TABLE_ENTRIES];
    
    static uint8_t                                   s_WriteBuffer[MAX_WRITE_CMD_PAYLOAD];
    static uint8_t                                   s_ReadBuffer[MAX_READ_CMD_PAYLOAD];
    
    static bool                                      s_StartProgramming;
    static uint8_t                                   s_FlashProgramBuffer[FLASH_WRITE_BLOCK_SIZE];
    static uint16_t                                  s_FlashProgramBufferPtr;
    
    static FILE* s_FilePointer;
    
    /**
     * Implement the I2C write transaction here. The sample code here sends
     * data to the controller via the Cypress USB-Serial adapter.
     */
    uint32_t WriteI2C(uint16_t             WriteDataLength,
    	uint8_t* WriteData,
    	DLPC_COMMON_CommandProtocolData_s* ProtocolData)
    {
    	bool Status = true;
    	//printf("Write I2C Starts, length %d!!! \n", WriteDataLength);
    	Status = CYPRESS_I2C_WriteI2C(WriteDataLength, WriteData);
    	if (Status != true)
    	{
    		//printf("Write I2C Error!!! \n");
    		return FAIL;
    	}
    
    	return SUCCESS;
    }
    
    /**
     * Implement the I2C write/read transaction here. The sample code here
     * receives data from the controller via the Cypress USB-Serial adapter.
     */
    uint32_t ReadI2C(uint16_t              WriteDataLength,
    	uint8_t* WriteData,
    	uint16_t                           ReadDataLength,
    	uint8_t* ReadData,
    	DLPC_COMMON_CommandProtocolData_s* ProtocolData)
    {
    	bool Status = 0;
    	//printf("Write/Read I2C Starts, length %d!!! \n", WriteDataLength);
    	Status = CYPRESS_I2C_WriteI2C(WriteDataLength, WriteData);
    	if (Status != true)
    	{
    		//printf("Write I2C Error!!! \n");
    		return FAIL;
    	}
    
    	Status = CYPRESS_I2C_ReadI2C(ReadDataLength, ReadData);
    	if (Status != true)
    	{
    		//printf("Read I2C Error!!! \n");
    		return FAIL;
    	}
    
    	return SUCCESS;
    }
    
    /**
     * Initialize the command layer by setting up the read/write buffers and
     * callbacks.
     */
    void InitConnectionAndCommandLayer()
    {
    	DLPC_COMMON_InitCommandLibrary(s_WriteBuffer,
    		sizeof(s_WriteBuffer),
    		s_ReadBuffer,
    		sizeof(s_ReadBuffer),
    		WriteI2C,
    		ReadI2C);
    
    	CYPRESS_I2C_ConnectToCyI2C();
    }
    
    void WriteTestPatternGridLines()
    {
    	/* Write Input Image Size */
    	DLPC34XX_WriteInputImageSize(MAX_WIDTH, MAX_HEIGHT);
    
    	/* Write Image Crop */
    	DLPC34XX_WriteImageCrop(0, 0, MAX_WIDTH, MAX_HEIGHT);
    
    	/* Write Display Size */
    	DLPC34XX_WriteDisplaySize(0, 0, MAX_WIDTH, MAX_HEIGHT);
    
    	/* Write Grid Lines */
    	DLPC34XX_GridLines_s GridLines;
    	GridLines.Border = DLPC34XX_BE_ENABLE;
    	GridLines.BackgroundColor = DLPC34XX_C_GREEN;
    	GridLines.ForegroundColor = DLPC34XX_C_MAGENTA;
    	GridLines.HorizontalForegroundLineWidth = 0xF;
    	GridLines.HorizontalBackgroundLineWidth = 0xF;
    	GridLines.VerticalForegroundLineWidth = 0xF;
    	GridLines.VerticalBackgroundLineWidth = 0xF;
    	DLPC34XX_WriteGridLines(&GridLines);
    
    	DLPC34XX_WriteOperatingModeSelect(DLPC34XX_OM_TEST_PATTERN_GENERATOR);
    	Sleep(5000);
    }
    
    void WriteTestPatternColorBar()
    {
    	/* Write Input Image Size */
    	DLPC34XX_WriteInputImageSize(MAX_WIDTH, MAX_HEIGHT);
    
    	/* Write Image Crop */
    	DLPC34XX_WriteImageCrop(0, 0, MAX_WIDTH, MAX_HEIGHT);
    
    	/* Write Display Size */
    	DLPC34XX_WriteDisplaySize(0, 0, MAX_WIDTH, MAX_HEIGHT);
    
    	/* Write Color Bar & Select Test Pattern */
    	DLPC34XX_WriteColorbars(DLPC34XX_BE_ENABLE);
    
    	DLPC34XX_WriteOperatingModeSelect(DLPC34XX_OM_TEST_PATTERN_GENERATOR);
    	Sleep(5000);
    }
    
    void WriteLabbCaic()
    {
    	//SetIntelliBright(bool EnableLabb, uint8_t LabbStrength, uint8_t LabbSharpness,
    	//                 bool EnableCaic, double CaicGain, bool EnableCaicDisplay,
    	//                 double *MaxPower, uint16_t *CaicRed, uint16_t *CaicGreen, uint16_t *CaicBlue)
    
    	DLPC34XX_WriteLocalAreaBrightnessBoostControl(DLPC34XX_LC_MANUAL, 5, 60);		/* Enable LABB */
    	DLPC34XX_WriteCaicImageProcessingControl(DLPC34XX_CGDS_P1024, true, 2.5, 0);	/* Enable CAIC */
    
    	DLPC34XX_WriteLedOutputControlMethod(DLPC34XX_LCM_AUTOMATIC);
    
    	double MaxPower;
    	DLPC34XX_ReadCaicLedMaxAvailablePower(&MaxPower);
    
    	uint16_t CaicRedCurrent, CaicGreenCurrent, CaicBlueCurrent;
    	DLPC34XX_ReadCaicRgbLedCurrent(&CaicRedCurrent, &CaicGreenCurrent, &CaicBlueCurrent);
    
    	DLPC34XX_OperatingMode_e CurrentOperatingMode;
    	DLPC34XX_ReadOperatingModeSelect(&CurrentOperatingMode);
    
    	if ((CurrentOperatingMode == DLPC34XX_OM_SPLASH_SCREEN) ||
    		(CurrentOperatingMode == DLPC34XX_OM_SENS_SPLASH_PATTERN))
    	{
    		DLPC34XX_WriteSplashScreenExecute();
    		Sleep(2000);
    	}
    	Sleep(5000);
    }
    
    void LoadFirmware()
    {
    	/* write up to 1024 bytes of data */
    	uint8_t FlashDataArray[1024];
    
    	/* Pattern File assumes to be in the \build\vs2017\dlpc343x folder */
    	//s_FilePointer = fopen("dlpc3470_7.4.0.img", "rb");
    	s_FilePointer = fopen("..\FWSel_DLPC3478_DLPA2005_pm1_i2c0x36_v9p0p1.img", "rb");
    	//s_FilePointer = fopen("..\DLP3010EVM-LC_9.0.1.img", "rb");
    	if (!s_FilePointer)
    	{
    		printf("Error opening the flash image file!");
    		return;
    	}
    	fseek(s_FilePointer, 0, SEEK_END);
    	uint32_t FlashDataSize = ftell(s_FilePointer);
    	fseek(s_FilePointer, 0, SEEK_SET);
    
    	/* Select Flash Data Block and Erase the Block */
    	DLPC34XX_WriteFlashDataTypeSelect(DLPC34XX_FDTS_ENTIRE_FLASH);
    	DLPC34XX_WriteFlashErase();
    
    	/* Read Short Status to make sure Erase is completed */
    	DLPC34XX_ShortStatus_s ShortStatus;
    	do
    	{
    		Sleep(1000);
    		DLPC34XX_ReadShortStatus(&ShortStatus);
    	} while (ShortStatus.FlashEraseComplete == DLPC34XX_FE_NOT_COMPLETE);
    
    	DLPC34XX_WriteFlashDataLength(1024);
    	fread(FlashDataArray, sizeof(FlashDataArray), 1, s_FilePointer);
    	DLPC34XX_WriteFlashStart(1024, FlashDataArray);
    
    	int32_t BytesLeft = FlashDataSize - 1024;
    	do
    	{
    		fread(FlashDataArray, sizeof(FlashDataArray), 1, s_FilePointer);
    		DLPC34XX_WriteFlashContinue(1024, FlashDataArray);
    
    		BytesLeft = BytesLeft - 1024;
    	} while (BytesLeft > 0);
    
    	fclose(s_FilePointer);
    }
    
    void LoadPreBuildPatternData()
    {
    	/* write up to 1024 bytes of data */
    	uint8_t PatternDataArray[1024];
    
    	/* Pattern File assumes to be in the \build\vs2017\dlpc347x folder */
    	s_FilePointer = fopen("pattern_data.bin", "rb");
    	if (!s_FilePointer)
    	{
    		printf("Error opening the binary file!");
    		return;
    	}
    	fseek(s_FilePointer, 0, SEEK_END);
    	uint32_t PatternDataSize = ftell(s_FilePointer);
    	fseek(s_FilePointer, 0, SEEK_SET);
    
    	/* Select Flash Data Block and Erase the Block */
    	DLPC34XX_WriteFlashDataTypeSelect(DLPC34XX_FDTS_ENTIRE_SENS_PATTERN_DATA);
    	DLPC34XX_WriteFlashErase();
    
    	/* Read Short Status to make sure Erase is completed */
    	DLPC34XX_ShortStatus_s ShortStatus;
    	do
    	{
    		DLPC34XX_ReadShortStatus(&ShortStatus);
    	} while (ShortStatus.FlashEraseComplete == DLPC34XX_FE_NOT_COMPLETE);
    
    	DLPC34XX_WriteFlashDataLength(1024);
    	fread(PatternDataArray, sizeof(PatternDataArray), 1, s_FilePointer);
    	//for (int i = 0; i < 1024; i++)
    	//{
    	//	printf("%3u ", PatternDataArray[i]);
    	//}
    	//printf("\n\n");
    
    	DLPC34XX_WriteFlashStart(1024, PatternDataArray);
    
    	int32_t BytesLeft = PatternDataSize - 1024;
    	do
    	{
    		fread(PatternDataArray, sizeof(PatternDataArray), 1, s_FilePointer);
    		//for (int i = 0; i < 1024; i++)
    		//{
    		//	printf("%3u ", PatternDataArray[i]);
    		//}
    		//printf("\n\n");
    
    		DLPC34XX_WriteFlashContinue(1024, PatternDataArray);
    		BytesLeft = BytesLeft - 1024;
    	} while (BytesLeft > 0);
    
    	fclose(s_FilePointer);
    }
    
    void LoadPatternOrderTableEntryfromFlash()
    {
    	DLPC34XX_PatternOrderTableEntry_s PatternOrderTableEntry;
    
    	/* Reload from Flash */
    	DLPC34XX_WritePatternOrderTableEntry(DLPC34XX_WC_RELOAD_FROM_FLASH, &PatternOrderTableEntry);
    }
    
    /**
     * A sample function that generates a 1-bit (binary) 1-D pattern
     * The function fills the byte array Data. Each byte in the in array corresponds
     * to a pixel. For a 1-bit pattern the value of each byte should be 1 or 0.
     */
    void PopulateOneBitPatternData(uint16_t Length, uint8_t* Data, uint16_t NumBars)
    {
    	uint16_t PixelPos = 0;
    	uint16_t BarPos = 0;
    	uint16_t BarWidth = Length / NumBars;
    	uint8_t  PixelData = 0;
    
    	for (; PixelPos < Length; PixelPos++)
    	{
    		Data[PixelPos] = PixelData;
    
    		BarPos++;
    		if (BarPos >= BarWidth)
    		{
    			BarPos = 0;
    			PixelData = (PixelData == 0 ? 1 : 0);
    		}
    	}
    }
    
    /**
     * A sample function that generates an 8-bit (gray scale) 1-D pattern
     * The function fills the byte array Data. Each byte in the in array corresponds
     * to a pixel. For an 8-bit pattern the value of each byte can be 0 - 255.
     */
    void PopulateEightBitPatternData(uint16_t Length, uint8_t* Data, uint16_t NumBars)
    {
    	uint16_t PixelPos = 0;
    	uint16_t BarPos = 0;
    	uint16_t BarWidth = Length / (2 * NumBars);
    	uint8_t  PixelData = 0;
    	int16_t  PixelDataInc = (int16_t)ceil(255.0 / BarWidth);
    
    	for (; PixelPos < Length; PixelPos++)
    	{
    		Data[PixelPos] = PixelData;
    
    		BarPos++;
    		if (BarPos >= BarWidth)
    		{
    			BarPos = 0;
    			PixelDataInc = -PixelDataInc;
    		}
    
    		PixelData = (uint8_t)(PixelData + PixelDataInc);
    	}
    }
    
    /**
     * Populates an array of DLPC34XX_INT_PAT_PatternSet_s
     */
    void PopulatePatternSetData(uint16_t DMDWidth, uint16_t DMDHeight)
    {
    	uint8_t                        HorzPatternIdx = 0;
    	uint8_t                        VertPatternIdx = 0;
    	uint8_t                        PatternIdx = 0;
    	uint8_t                        PatternSetIdx = 0;
    	uint8_t                        Index;
    	uint16_t                       NumBars;
    	DLPC34XX_INT_PAT_PatternSet_s* PatternSet;
    
    	/* Create a 1-bit (binary) Vertical Pattern Set */
    	PatternSet = &s_PatternSets[PatternSetIdx++];
    	PatternSet->BitDepth = DLPC34XX_INT_PAT_BITDEPTH_ONE;
    	PatternSet->Direction = DLPC34XX_INT_PAT_DIRECTION_VERTICAL;
    	PatternSet->PatternCount = NUM_ONE_BIT_VERTICAL_PATTERNS;
    	PatternSet->PatternArray = &s_Patterns[PatternIdx];
    	for (Index = 0; Index < NUM_ONE_BIT_VERTICAL_PATTERNS; Index++)
    	{
    		NumBars = 2 * (Index + 1);
    		PopulateOneBitPatternData(DMDWidth, s_VerticalPatternData[VertPatternIdx], NumBars);
    		s_Patterns[PatternIdx].PixelArray = s_VerticalPatternData[VertPatternIdx];
    		s_Patterns[PatternIdx].PixelArrayCount = DMDWidth;
    		PatternIdx++;
    		VertPatternIdx++;
    	}
    
    	/* Create a 1-bit (binary) Horizontal Pattern Set */
    	PatternSet = &s_PatternSets[PatternSetIdx++];
    	PatternSet->BitDepth = DLPC34XX_INT_PAT_BITDEPTH_ONE;
    	PatternSet->Direction = DLPC34XX_INT_PAT_DIRECTION_HORIZONTAL;
    	PatternSet->PatternCount = NUM_ONE_BIT_HORIZONTAL_PATTERNS;
    	PatternSet->PatternArray = &s_Patterns[PatternIdx];
    	for (Index = 0; Index < NUM_ONE_BIT_HORIZONTAL_PATTERNS; Index++)
    	{
    		NumBars = 2 * (Index + 1);
    		PopulateOneBitPatternData(DMDHeight, s_HorizontalPatternData[HorzPatternIdx], NumBars);
    		s_Patterns[PatternIdx].PixelArray = s_HorizontalPatternData[HorzPatternIdx];
    		s_Patterns[PatternIdx].PixelArrayCount = DMDHeight;
    		PatternIdx++;
    		HorzPatternIdx++;
    	}
    }
    
    /**
     * Populates an array of DLPC34XX_INT_PAT_PatternOrderTableEntry_s
     */
    void PopulatePatternTableData()
    {
    	DLPC34XX_INT_PAT_PatternOrderTableEntry_s* PatternOrderTableEntry;
    	uint32_t                                   PatternOrderTableIdx = 0;
    	uint32_t                                   PatternSetIdx = 0;
    
    	/* Pattern Table Entry 0 - uses Pattern Set 0 */
    	PatternOrderTableEntry = &s_PatternOrderTable[PatternOrderTableIdx++];
    	PatternOrderTableEntry->PatternSetIndex = PatternSetIdx;
    	PatternOrderTableEntry->NumDisplayPatterns = s_PatternSets[PatternSetIdx++].PatternCount;
    	PatternOrderTableEntry->IlluminationSelect = DLPC34XX_INT_PAT_ILLUMINATION_BLUE;
    	PatternOrderTableEntry->InvertPatterns = false;
    	PatternOrderTableEntry->PreIlluminationDarkTimeInMicroseconds = 2665;
    	PatternOrderTableEntry->IlluminationTimeInMicroseconds = 500000;
    	PatternOrderTableEntry->PostIlluminationDarkTimeInMicroseconds = 471;
    
    	/* Pattern Table Entry 1 - uses Pattern Set 1 */
    	PatternOrderTableEntry = &s_PatternOrderTable[PatternOrderTableIdx++];
    	PatternOrderTableEntry->PatternSetIndex = PatternSetIdx;
    	PatternOrderTableEntry->NumDisplayPatterns = s_PatternSets[PatternSetIdx++].PatternCount;
    	PatternOrderTableEntry->IlluminationSelect = DLPC34XX_INT_PAT_ILLUMINATION_BLUE;
    	PatternOrderTableEntry->InvertPatterns = false;
    	PatternOrderTableEntry->PreIlluminationDarkTimeInMicroseconds = 5860;
    	PatternOrderTableEntry->IlluminationTimeInMicroseconds = 500000;
    	PatternOrderTableEntry->PostIlluminationDarkTimeInMicroseconds = 1035;
    }
    
    void CopyDataToFlashProgramBuffer(uint8_t* Length, uint8_t** DataPtr)
    {
    	while ((*Length >= 1) &&
    		(s_FlashProgramBufferPtr < sizeof(s_FlashProgramBuffer)))
    	{
    		s_FlashProgramBuffer[s_FlashProgramBufferPtr] = **DataPtr;
    		s_FlashProgramBufferPtr++;
    		(*DataPtr)++;
    		(*Length)--;
    	}
    }
    
    void ProgramFlashWithDataInBuffer(uint16_t Length)
    {
    	s_FlashProgramBufferPtr = 0;
    
    	if (s_StartProgramming)
    	{
    		s_StartProgramming = false;
    		DLPC34XX_WriteFlashStart(Length, s_FlashProgramBuffer);
    	}
    	else
    	{
    		DLPC34XX_WriteFlashContinue(Length, s_FlashProgramBuffer);
    	}
    }
    
    void BufferPatternDataAndProgramToFlash(uint8_t Length, uint8_t* Data)
    {
    	/* Copy data that can fit in the flash programming buffer */
    	CopyDataToFlashProgramBuffer(&Length, &Data);
    
    	/* Write data to flash if the buffer is full */
    	if (s_FlashProgramBufferPtr >= sizeof(s_FlashProgramBuffer))
    	{
    		ProgramFlashWithDataInBuffer((uint16_t)sizeof(s_FlashProgramBuffer));
    	}
    
    	/* Copy remaining data (if any) to the flash programming buffer */
    	CopyDataToFlashProgramBuffer(&Length, &Data);
    }
    
    void GenerateAndProgramPatternData(DLPC34XX_INT_PAT_DMD_e DMD, bool EastWestFlip, bool LongAxisFlip)
    {
    	s_StartProgramming = true;
    	s_FlashProgramBufferPtr = 0;
    
    	/* Let the controller know that we're going to program pattern data */
    	DLPC34XX_WriteFlashDataTypeSelect(DLPC34XX_FDTS_ENTIRE_SENS_PATTERN_DATA);
    
    	/* Erase the flash sectors that store pattern data */
    	DLPC34XX_WriteFlashErase();
    
    	/* Read Short Status to make sure Erase is completed */
    	DLPC34XX_ShortStatus_s ShortStatus;
    	do
    	{
    		DLPC34XX_ReadShortStatus(&ShortStatus);
    	} while (ShortStatus.FlashEraseComplete == DLPC34XX_FE_NOT_COMPLETE);
    
    	/* To program the flash, send blocks of data of up to 1024 bytes
    	 * to the controller at a time. Repeat the process until the entire
    	 * data is programmed to the flash.
    	 * Let the controller know the size of a data block that will be
    	 * transferred at a time.
    	 */
    	DLPC34XX_WriteFlashDataLength(sizeof(s_FlashProgramBuffer));
    
    	/* Generate pattern data and program it to the flash.
    	 *
    	 * The DLPC34XX_INT_PAT_GeneratePatternDataBlock() function calls the
    	 * BufferPatternDataAndProgramToFlash() function several times while it
    	 * generates pattern data.
    	 *
    	 * The BufferPatternDataAndProgramToFlash() function buffers data received,
    	 * programming the buffer content only when it is full. This is done in an
    	 * effort to make flash writes more efficient, overall greatly reducing the
    	 * time it takes to program the pattern data.
    	 *
    	 * After returning from the DLPC34XX_INT_PAT_GeneratePatternBlock() function,
    	 * check if there is any data left in the buffer and program it. This needs
    	 * to be done since the BufferPatternDataAndProgramToFlash() function only
    	 * programs the buffer content if full.
    	 */
    	DLPC34XX_INT_PAT_GeneratePatternDataBlock(DMD,
    		NUM_PATTERN_SETS,
    		s_PatternSets,
    		NUM_PATTERN_ORDER_TABLE_ENTRIES,
    		s_PatternOrderTable,
    		BufferPatternDataAndProgramToFlash,
    		EastWestFlip,
    		LongAxisFlip);
    	if (s_FlashProgramBufferPtr > 0)
    	{
    		/* Resend the block size since it could be less than
    		 * the previously specified size
    		 */
    		DLPC34XX_WriteFlashDataLength(s_FlashProgramBufferPtr);
    
    		ProgramFlashWithDataInBuffer(s_FlashProgramBufferPtr);
    	}
    }
    
    void WriteDataToFile(uint8_t Length, uint8_t* Data)
    {
    	fwrite(Data, 1, Length, s_FilePointer);
    }
    
    void GenerateAndWritePatternDataToFile(DLPC34XX_INT_PAT_DMD_e DMD, char* FilePath, bool EastWestFlip, bool LongAxisFlip)
    {
    	s_FilePointer = fopen(FilePath, "wb");
    
    	/* Generate pattern data and write it to the flash.
    	 * The DLPC34XX_INT_PAT_GeneratePatternDataBlock() function will call the
    	 * WriteDataToFile() function several times while it packs sections of the
    	 * pattern data.
    	 */
    
    	 /*for (int i = 0; i < 4; i++)
    	 {
    		 std::cout << i << " " << s_PatternSets << std::endl;
    	 }*/
    
    	DLPC34XX_INT_PAT_GeneratePatternDataBlock(DMD,
    		NUM_PATTERN_SETS,
    		s_PatternSets,
    		NUM_PATTERN_ORDER_TABLE_ENTRIES,
    		s_PatternOrderTable,
    		WriteDataToFile,
    		EastWestFlip,
    		LongAxisFlip);
    
    	fclose(s_FilePointer);
    }
    
    void main()
    {
    	// Initialize the command layer by setting up the read / write buffers and callbacks.
    	InitConnectionAndCommandLayer();
    
    	/* TI DLP Pico EVMs use a GPIO handshake scheme for the controller I2C bus
    	 * arbitration. Call this method if using a TI EVM, remove otherwise
    	 */
    	bool Status = CYPRESS_I2C_RequestI2CBusAccess();
    	if (Status != true)
    	{
    		printf("Error Request I2C Bus ACCESS!!!");
    		return;
    	}
    
    	//uint32_t dmdID;
    	//DLPC34XX_DmdDataSelection_e dmdDataSelection = (DLPC34XX_DmdDataSelection_e)0;
    	//DLPC34XX_ReadDmdDeviceId(dmdDataSelection , &dmdID);
    	//printf("DMD Device ID = %u \n", dmdID);
    
    	DLPC34XX_ControllerDeviceId_e controllerID = (DLPC34XX_ControllerDeviceId_e)0;
    	DLPC34XX_ReadControllerDeviceId(&controllerID);
    	printf("Controller Device ID = %d \n", controllerID);
    
    	uint16_t PixelsPerLine, LinesPerFrame;
    	DLPC34XX_ReadInputImageSize(&PixelsPerLine, &LinesPerFrame);
    	printf("Input Image Size = %u, %u \n", PixelsPerLine, LinesPerFrame);
    
    	/* ***** Write Test Patterns ***** */
    	//WriteTestPatternGridLines();
    	//WriteTestPatternColorBar();
    
    	//WriteLabbCaic();
    
    	/* ***** Test Internal Pattern Sensing ***** */
    	bool LoadFromFirmware = false;
    	bool LoadFromBin = false;	// Switch to load pattern from saved file or generated
    	bool LoadFromBmp = false;
    
    	if (LoadFromFirmware)
    	{
    		LoadFirmware();
    	}
    	else if (LoadFromBin)
    	{
    		/* Load pre-build Pattern Table and Sets */
    		LoadPreBuildPatternData();
    		LoadPatternOrderTableEntryfromFlash();
    	}
    	else
    	{
    		/* Prepare the data for pattern data block generation */
    		PopulatePatternSetData(MAX_WIDTH, MAX_HEIGHT);
    		PopulatePatternTableData();
    
    		/* Stop pattern display */
    		DLPC34XX_WriteInternalPatternControl(DLPC34XX_PC_STOP, 0x00);
    
    		/* Generate and program the pattern data to the controller flash */
    		GenerateAndProgramPatternData(DLPC34XX_INT_PAT_DMD_DLP3010, false, false);
    
    		/* Load Pattern Order Table Entry from Flash */
    		LoadPatternOrderTableEntryfromFlash();
    
    		/* Generate and write pattern data to a file */
    		GenerateAndWritePatternDataToFile(DLPC34XX_INT_PAT_DMD_DLP3010, (char*)"pattern_data.bin", false, false);
    	}
    
    	/* Display patterns */
    	DLPC34XX_WriteOperatingModeSelect(DLPC34XX_OM_SENS_INTERNAL_PATTERN);
    	DLPC34XX_WriteTriggerOutConfiguration(DLPC34XX_TT_TRIGGER1, DLPC34XX_TE_ENABLE, DLPC34XX_TI_INVERTED, 0);
    	DLPC34XX_WriteTriggerOutConfiguration(DLPC34XX_TT_TRIGGER2, DLPC34XX_TE_ENABLE, DLPC34XX_TI_INVERTED, 0);
    
    	DLPC34XX_WriteInternalPatternControl(DLPC34XX_PC_START, 1);
    	Sleep(120000);
    	DLPC34XX_WriteInternalPatternControl(DLPC34XX_PC_STOP, 0x00);
    
    	CYPRESS_I2C_RelinquishI2CBusAccess();
    }

    This is whole code(c++) I used, which is almost same with the original sample from TI-API.

    Please let me know where the problem is.

    Best regards,

    Junyoung

  • Hi Junyoung,

    Can you try creating a pattern.bin file via the DLP GUI with two or more pattern sets and flashing that .bin? You can also use a oscilloscope to determine if the trigger 1 and trigger 2 are indicating two sets being illuminated or just one. This will help narrow down where the issue is.

    Best,

    Maximus

  • Hi Maximus,

    Thank you for your kind reply.

    1. for your request,

    I tried creating a pattern.bin file with DLP GUI with two pattern sets and I got "Warning! Pattern's timings are not validated before saving to file" message.

    I used 4 patterns, 342[us] pre-exposure dark time, 127598[us] exposure time, and 62[us] post-exposure dark time for the first pattern set.

    and used 11 patterns with the same timings with the first pattern set for the second pattern set.

    2. additional question

    How to restart or reboot the projector in software? I found TI GUI restarts the projector after loading patterns into flash, but I couldn't find which command restarts the projector. (Without restarts, pattern does not change so I have restarted with the switch on the board.)

    Thank you,

    Junyoung

  • Hello Junyoung,

    1) This is normal, if you'd like to validate the timings you can send the proper I2C command (Read Validate Exposure Time (9Dh)) to validate them or try uploading via the GUI and see if you get an error. 

    2) Are you using a DLP EVM or a custom board? To restart you should drive proj_on low and then high again.

    Best,

    Maximus