#if defined(__ADSPBF537__)		/* __ADSPBF537__ */
#include <cdefBF537.h>
#elif defined(__ADSPBF526__)	/* __ADSPBF526__ */
#include <cdefBF526.h>
#include <bfrom.h>
#elif defined(__ADSPBF548__)	/* __ADSPBF548__ */
#include <cdefBF548.h>
#include <bfrom.h>
#elif defined(__ADSPBF518__)	/* __ADSPBF518__ */
#include <cdefBF518.h>
#include <bfrom.h>
#else							/* NOT DEFINED */
#error *** Processor not supported ***
#endif

#include <stdio.h>
#include <sys\exception.h>	// Interrupt Handling Header
#include <ccblkfn.h>
#include <sysreg.h>
#include <signal.h>
#include "..\lcd_buffers.h"
#include "..\LCD\lq035q1dh02.h"
#include "..\TouchScreen\ad7879.h"


section("sdram0") u8 PicsFrame0[LCD_PIXELS_PER_LINE * 3 * LCD_LINES_PER_FRAME + 960] =
{
	#include "image1.dat"
};

section("sdram0") u8 PicsFrame1[LCD_PIXELS_PER_LINE * 3 * LCD_LINES_PER_FRAME + 960] =
{
	#include "image2.dat"
};

section("sdram0") u8 PicsFrame2[LCD_PIXELS_PER_LINE * 3 * LCD_LINES_PER_FRAME + 960] =
{
	#include "image3.dat"
};


/* buffer for the image to be displayed */
extern u16 Frame0[];

/* This is part of the front porch and will not
   be displayed									*/
extern u16 TempFrame[];

/* Dummy buffer to account for the front porch  */
extern DESCRIPTOR_LARGE DummyBuffer[];

/* array of descriptors for DMA */
extern DESCRIPTOR_LARGE Buffer1[];
DESCRIPTOR_LARGE Buffer2[LCD_NUM_FRAMES_DISPLAY];
DESCRIPTOR_LARGE Buffer3[LCD_NUM_FRAMES_DISPLAY];


/*******************************************************************
*   Function:    Convert_RGB888_To_RGB565
*   Description: Converts RGB888 images to RGB565
*******************************************************************/
void Convert_RGB888_To_RGB565(u8 *Buf)
{
	u8 red, green, blue;
	u16 Value16Bit;
	u16 Value16BitSwapped;
	u16 *puBuf16 = (u16 *)Buf;
	int i = 0;
	int j = 0;

	for( i = 0; i < LCD_PIXELS_PER_LINE * 3 * LCD_LINES_PER_FRAME; i+=3 )
	{
		red = Buf[i];
		green = Buf[i+1];
		blue = Buf[i+2];

		// convert RGB888 to RGB565
		red >>= 3;
		green >>= 2;
		blue >>= 3;

		// set RGB values in approprate bit positions
		Value16Bit = (red << 11) | (green << 5) | blue;

		// fill same buffer with RGB565 data
		puBuf16[j++] = Value16Bit;
	}

}

/*******************************************************************
*   Function:    LCD_DISPLAY_PICS
*   Description: Main test routine will get launched from the POST
*				 framework.
*******************************************************************/
void LCD_DISPLAY_PICS(void)
{
	volatile int i = 0;
	u32     Line,Pixel,ColorId;

#if defined(__ADSPBF548__)	/* __ADSPBF548__ */
	*pPORTB_DIR_SET = PB2;
	*pPORTB_CLEAR = PB2;
#endif
	
	
	/* turn on the LCD backlight */
	Write_AD7879(CONTROL_REG_2, 0x2000);
	
	/* convert the RGB888 images to the appropriate RGB565 */
	Convert_RGB888_To_RGB565(PicsFrame0);
	Convert_RGB888_To_RGB565(PicsFrame1);
	Convert_RGB888_To_RGB565(PicsFrame2);


	/* REV = 1, TB = 1, BGR = 0  */
	Select_LQ035Q1DH02_Register(0x01);
	Write_LQ035Q1DH02_Data(0x22EF);

	/* Set SHUT(Bit 0) to 0 which takes the LCD out of sleep mode
	   because it is by default in sleep mode via a resistor
	   Set CM(bit 8) to 0 for 262k color mode						*/
	Select_LQ035Q1DH02_Register(0x11);
	Write_LQ035Q1DH02_Data(0x0000);

#if defined(__ADSPBF548__)	/* __ADSPBF548__ */
	/* for the BF548 we don't need the dummy buffers */
#else
	DummyBuffer[0].pNext             = &DummyBuffer[1];   /* chain to next buffer in the list */
    DummyBuffer[0].StartAddress      = TempFrame;
    DummyBuffer[0].XCount            = H_ACTPIX;
    DummyBuffer[0].XModify           = 2;
    DummyBuffer[0].YCount            = 2;
    DummyBuffer[0].YModify           = 2;
    DummyBuffer[0].Config           	=	DMAEN 		|	// enable DMA
											WDSIZE_16	|	// WDSIZE=01, 16 bit
											DMA2D 		|	// DMA2D=1. 2D
											NDSIZE_9	|	// NDSIZE=9
									  		FLOW_LARGE;		// large list descriptor mode

	DummyBuffer[1].pNext             = &Buffer1[0];   /* chain to next buffer in the list */
    DummyBuffer[1].StartAddress      = TempFrame;
    DummyBuffer[1].XCount            = H_ACTPIX;
    DummyBuffer[1].XModify           = 2;
    DummyBuffer[1].YCount            = 2;
    DummyBuffer[1].YModify           = 2;
    DummyBuffer[1].Config           	=	DMAEN 		|	// enable DMA
											WDSIZE_16	|	// WDSIZE=01, 16 bit
											DMA2D 		|	// DMA2D=1. 2D
											NDSIZE_9	|	// NDSIZE=9
									  		FLOW_LARGE;		// large list descriptor mode

#endif

	/* FOR (Number of output 2D buffers) */
    for (i = 0; i < LCD_NUM_FRAMES_DISPLAY; i++)
    {
    	Buffer1[i].pNext             = &Buffer1[i + 1];   /* chain to next buffer in the list */
    	Buffer1[i].StartAddress      = PicsFrame0;
        Buffer1[i].XCount            = H_ACTPIX;
        Buffer1[i].XModify           = 2;
        Buffer1[i].YCount            = V_LINES;
        Buffer1[i].YModify           = 2;
        Buffer1[i].Config           	=	DMAEN 		|	// enable DMA
											WDSIZE_16	|	// WDSIZE=01, 16 bit
											DMA2D 		|	// DMA2D=1. 2D
											NDSIZE_9	|	// NDSIZE=9
									  		FLOW_LARGE;		// large list descriptor mode
    }

    // make the buffer loop back around
	Buffer1[LCD_NUM_FRAMES_DISPLAY - 1].pNext = &Buffer2[0];

	/* FOR (Number of output 2D buffers) */
    for (i = 0; i < LCD_NUM_FRAMES_DISPLAY; i++)
    {
    	Buffer2[i].pNext             = &Buffer2[i + 1];   /* chain to next buffer in the list */
    	Buffer2[i].StartAddress      = PicsFrame1;
        Buffer2[i].XCount            = H_ACTPIX;
        Buffer2[i].XModify           = 2;
        Buffer2[i].YCount            = V_LINES;
        Buffer2[i].YModify           = 2;
        Buffer2[i].Config           	=	DMAEN 		|	// enable DMA
											WDSIZE_16	|	// WDSIZE=01, 16 bit
											DMA2D 		|	// DMA2D=1. 2D
											NDSIZE_9	|	// NDSIZE=9
									  		FLOW_LARGE;		// large list descriptor mode
    }

	// make the buffer loop back around
	Buffer2[LCD_NUM_FRAMES_DISPLAY - 1].pNext = &Buffer3[0];

	/* FOR (Number of output 2D buffers) */
    for (i = 0; i < LCD_NUM_FRAMES_DISPLAY; i++)
    {
    	Buffer3[i].pNext             = &Buffer3[i + 1];   /* chain to next buffer in the list */
    	Buffer3[i].StartAddress      = PicsFrame2;
        Buffer3[i].XCount            = H_ACTPIX;
        Buffer3[i].XModify           = 2;
        Buffer3[i].YCount            = V_LINES;
        Buffer3[i].YModify           = 2;
        Buffer3[i].Config           	=	DMAEN 		|	// enable DMA
											WDSIZE_16	|	// WDSIZE=01, 16 bit
											DMA2D 		|	// DMA2D=1. 2D
											NDSIZE_9	|	// NDSIZE=9
									  		FLOW_LARGE;		// large list descriptor mode
    }
  
	// make the buffer loop back around
	Buffer3[LCD_NUM_FRAMES_DISPLAY - 1].pNext = &Buffer1[0];

	LQ035Q1DH02_Init_PPI_Ints();	/* initialize PPI interrupts */

	LQ035Q1DH02_Init_TIMER0();			/* init timer 0( horizontal FS ) */
	LQ035Q1DH02_Init_TIMER1();			/* init timer 1( vertical FS ) */
	LQ035Q1DH02_Init_PPI();				/* initialize PPI */

#if defined(__ADSPBF548__)	/* __ADSPBF548__ */
	LQ035Q1DH02_Init_DMA(Buffer1);	/* initialize the DMA */
#else
	LQ035Q1DH02_Init_DMA(DummyBuffer);	/* initialize the DMA */
#endif

	/* start PPI */
    LQ035Q1DH02_Enable_PPI();

	/* Frame sync 2 (VS) needs to start at least one PPI clk earlier */
	LQ035Q1DH02_Enable_TIMER1();

	/* now start frame sync 1 */
	LQ035Q1DH02_Enable_TIMER0();

    /* exit out of here and into the main
       calling function to wait for the user
       to select a test */
   	

}/* end main */

#ifdef _STANDALONE_

void main(void)
{
#if defined(__ADSPBF537__)		/* __ADSPBF537__ */

	*pSIC_IWR |= 0x1;		/* enable PLL wakeup */
	*pPLL_CTL =  0x3000;	/* MSEL= x39,  DF= %2 */
	
	ssync();
 	idle();					/* put in idle */
	
	*pPLL_DIV =  0x0005;	/* CSEL= %1, SSEL= %4 */

	/* The -6AV/AVX BF537 DSP that are now shipping requires
	   the internal regulator to be set to 1.3V in order to 
	   run at 600 Mhz. The VLEV[3:0] bits in VR_CTL will need to 
	   be set to 1111. */
	*pVR_CTL = 0x42FB;
	
#elif defined(__ADSPBF526__)	/* __ADSPBF526__ */

	/* use Blackfin ROM SysControl() to change the PLL */
    ADI_SYSCTRL_VALUES sys_cntrl_struct;

	sys_cntrl_struct.uwPllCtl = 0x2000;		/* (25MHz CLKIN x (MSEL=16))::CCLK = 400MHz */
	sys_cntrl_struct.uwPllDiv = 0x0005;		/* (400MHz/(SSEL=5))::SCLK = 80MHz */

	bfrom_SysControl( SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV,
					  &sys_cntrl_struct, NULL);

#elif defined(__ADSPBF548__)	/* __ADSPBF548__ */

	/* use Blackfin ROM SysControl() to change the PLL */
    ADI_SYSCTRL_VALUES sys_cntrl_struct;

	sys_cntrl_struct.uwPllCtl = 0x2000;		/* (25MHz CLKIN x (MSEL=16))::CCLK = 400MHz */
	sys_cntrl_struct.uwPllDiv = 0x0004;		/* (400MHz/(SSEL=4))::SCLK = 100MHz */

	bfrom_SysControl( SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV,
					  &sys_cntrl_struct, NULL);
					  
#elif defined(__ADSPBF518__)	/* __ADSPBF518__ */

	/* use Blackfin ROM SysControl() to change the PLL */
    ADI_SYSCTRL_VALUES sys_cntrl_struct;

	sys_cntrl_struct.uwPllCtl = 0x2000;		/* (25MHz CLKIN x (MSEL=16))::CCLK = 400MHz */
	sys_cntrl_struct.uwPllDiv = 0x0005;		/* (400MHz/(SSEL=5))::SCLK = 80MHz */

	bfrom_SysControl( SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV,
					  &sys_cntrl_struct, NULL);
					  
#else							/* NOT DEFINED */
#error *** Processor not supported ***
#endif
					  
	LCD_DISPLAY_PICS();
	
	while(1)
	{
		asm("nop;");
		asm("nop;");
		asm("nop;");	
	}
}

#endif /* #ifdef _STANDALONE_ */
