/**
 * \file  rasterDisplay.c
 *
 * \brief Sample application for raster
 */

/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 
*
*  Redistribution and use in source and binary forms, with or without 
*  modification, are permitted provided that the following conditions 
*  are met:
*
*    Redistributions of source code must retain the above copyright 
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the 
*    documentation and/or other materials provided with the   
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "raster.h"
#include "psc.h"
#include "interrupt.h"
#include "soc_OMAPL138.h"
#include "hw_psc_OMAPL138.h"
#include "evmOMAPL138.h"
#include "image.h"

#define LCD_CLK  150000000
#define PALETTE_SIZE 32
#define PALETTE_OFFSET    4

#define LCD_VGA

/* VGA 640 x 480 - ~64Hz Refresh*/
#ifdef LCD_VGA
	#define LCD_WIDTH 				640
	#define LCD_HEIGHT 				480
	#define LCD_HFP					13		//  Horiz front porch
	#define LCD_HBP					100		//  Horiz back porch
	#define LCD_HSW					96		//  Horiz Sync width
	#define LCD_VFP					2		//  Vert front porch
	#define LCD_VBP					2		//  Vert back porch
	#define LCD_VSW					4		//  Vert Sync width
	#define LCD_PXL_CLK				25000000	 /* 150000000 / 6 */
	#define LCD_INVERT_PXL_CLK		1
#endif

/* WVGA 800 x 480 ~ 60 Hz Refresh */
#ifdef LCD_WVGA
	#define LCD_WIDTH 				800
	#define LCD_HEIGHT 				480
	#define LCD_HFP					10		//  Horiz front porch
	#define LCD_HBP					50		//  Horiz back porch
	#define LCD_HSW					96		//  Horiz Sync width
	#define LCD_VFP					2		//  Vert front porch
	#define LCD_VBP					2		//  Vert back porch
	#define LCD_VSW					4		//  Vert Sync width
	#define LCD_PXL_CLK				25000000  /* 150000000 / 6 */
	#define LCD_INVERT_PXL_CLK		1
	#endif

/* SVGA 800 x 600 ~ 60 Hz Refresh */
#ifdef LCD_SVGA
	#define LCD_WIDTH 				800
	#define LCD_HEIGHT 				600
	#define LCD_HFP					56		//  Horiz front porch
	#define LCD_HBP					64		//  Horiz back porch
	#define LCD_HSW					120		//  Horiz Sync width
	#define LCD_VFP					37		//  Vert front porch
	#define LCD_VBP					23		//  Vert back porch
	#define LCD_VSW					6		//  Vert Sync width
	#define LCD_PXL_CLK				40000000  /* 150000000 / 6 */
	#define LCD_INVERT_PXL_CLK		0
#endif

/******************************************************************************
**                      INTERNAL FUNCTION PROTOTYPES
*******************************************************************************/
static void SetupIntc(void);
static void SetUpLCD(void);
static void LCDIsr(void);

/******************************************************************************
**                      INTERNAL VARIABLE DEFINITIONS
*******************************************************************************/


/******************************************************************************
**                      INTERNAL FUNCTION DEFINITIONS
*******************************************************************************/
int main(void)
{
 //   SetupIntc();

    SetUpLCD();
  
    /* configuring the base ceiling */
    RasterDMAFBConfig(SOC_LCDC_0_REGS, 
                      (unsigned int)image1,
                      (unsigned int)image1 + sizeof(image1) - 2,
                      0);

    RasterDMAFBConfig(SOC_LCDC_0_REGS,
                      (unsigned int)image1,
                      (unsigned int)image1 + sizeof(image1) - 2,
                      1);

    /* enable End of frame interrupt */
    RasterEndOfFrameIntEnable(SOC_LCDC_0_REGS);

    /* enable raster */
    RasterEnable(SOC_LCDC_0_REGS);
 
    while(1); 

}

/*
** Configures raster to display image 
*/
static void SetUpLCD(void)
{
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_LCDC, PSC_POWERDOMAIN_ALWAYS_ON,
             PSC_MDCTL_NEXT_ENABLE);

    LCDPinMuxSetup();

    /* Configure backlight/power control pins */
    ConfigRasterDisplayEnable();

    /* disable raster */
    RasterDisable(SOC_LCDC_0_REGS);
    
    /* configure the pclk */
    RasterClkConfig(SOC_LCDC_0_REGS, LCD_PXL_CLK, LCD_CLK);

    /* configuring DMA of LCD controller */ 
    RasterDMAConfig(SOC_LCDC_0_REGS, RASTER_DOUBLE_FRAME_BUFFER,
                    RASTER_BURST_SIZE_16, RASTER_FIFO_THRESHOLD_8,
                    RASTER_BIG_ENDIAN_DISABLE);

    /* configuring modes(ex:tft or stn,color or monochrome etc) for raster controller */
    RasterModeConfig(SOC_LCDC_0_REGS, RASTER_DISPLAY_MODE_TFT,
                     RASTER_PALETTE_DATA, RASTER_COLOR, RASTER_RIGHT_ALIGNED);

    /* frame buffer data is ordered from least to Most significant bye */
    RasterLSBDataOrderSelect(SOC_LCDC_0_REGS);
    
    /* disable nibble mode */
    RasterNibbleModeDisable(SOC_LCDC_0_REGS);
   
     /* configuring the polarity of timing parameters of raster controller */
    RasterTiming2Configure(SOC_LCDC_0_REGS, RASTER_FRAME_CLOCK_LOW |
                                            RASTER_LINE_CLOCK_LOW  |
                                            RASTER_PIXEL_CLOCK_LOW |
                                            RASTER_SYNC_EDGE_RISING|
                                            RASTER_SYNC_CTRL_ACTIVE|
                                            RASTER_AC_BIAS_HIGH     , 0, 255);

	/* configuring horizontal timing parameter */
   RasterHparamConfig(SOC_LCDC_0_REGS, LCD_HEIGHT, LCD_HSW, LCD_HFP, LCD_HBP);

    /* configuring vertical timing parameters */
   RasterVparamConfig(SOC_LCDC_0_REGS, LCD_WIDTH, LCD_VSW, LCD_VFP, LCD_VBP);

   /* configuring fifo delay to */
   RasterFIFODMADelayConfig(SOC_LCDC_0_REGS, 2);
}

/*
** configures arm interrupt controller to generate raster interrupt 
*/
static void SetupIntc(void)
{
#ifdef _TMS320C6X
	// Initialize the DSP interrupt controller
	IntDSPINTCInit();

	// Register ISR to vector table
	IntRegister(C674X_MASK_INT4, LCDIsr);

	// Map system interrupt to DSP maskable interrupt
	IntEventMap(C674X_MASK_INT4, SYS_INT_LCDC_INT);

	// Enable DSP maskable interrupt
	IntEnable(C674X_MASK_INT4);

	// Enable DSP interrupts
	IntGlobalEnable();
#else
    /* Initialize the ARM Interrupt Controller.*/
    IntAINTCInit();

    /* Register the ISR in the Interrupt Vector Table.*/
    IntRegister(SYS_INT_LCDINT, LCDIsr);

    /* Set the channnel number 2 of AINTC for LCD system interrupt.  */
    IntChannelSet(SYS_INT_LCDINT, 2);

    /* Enable the System Interrupts for AINTC.*/
    IntSystemEnable(SYS_INT_LCDINT);

    /* Enable IRQ in CPSR.*/
    IntMasterIRQEnable();

    /* Enable the interrupts in GER of AINTC.*/
    IntGlobalEnable();

    /* Enable the interrupts in HIER of AINTC.*/
    IntIRQEnable();
#endif
}

/*
** For each end of frame interrupt base and ceiling is reconfigured 
*/
static void LCDIsr(void)
{
    unsigned int  status;

#ifdef _TMS320C6X
    IntEventClear(SYS_INT_LCDC_INT);
#else
    IntSystemStatusClear(SYS_INT_LCDINT);
#endif

    status = RasterIntStatus(SOC_LCDC_0_REGS,RASTER_END_OF_FRAME0_INT_STAT |
                                             RASTER_END_OF_FRAME1_INT_STAT );

    status = RasterClearGetIntStatus(SOC_LCDC_0_REGS, status);   

//    if (status & RASTER_END_OF_FRAME0_INT_STAT)
//    {
        RasterDMAFBConfig(SOC_LCDC_0_REGS, 
                          (unsigned int)image1,
                          (unsigned int)image1 + sizeof(image1) - 2,
                          0);
//    }

//    if(status & RASTER_END_OF_FRAME1_INT_STAT)
//    {
//        RasterDMAFBConfig(SOC_LCDC_0_REGS,
//                          (unsigned int)image1,
//                          (unsigned int)image1 + sizeof(image1) - 2,
//                          1);
//    }
}

/***************************** End Of File ************************************/
