/**
 * \file   gpioLEDBlink.c
 *
 *  \brief  This application uses a GPIO pin to blink the LED.
 *
 *          Application Configurations:
 *
 *              Modules Used:
 *                  GPIO1
 *
 *              Configuration Parameters:
 *                  None
 *
 *          Application Use Case:
 *              1) The GPIO pin GPIO1[23] is used as an output pin.
 *              2) This pin is alternately driven HIGH and LOW. A finite delay
 *                 is given to retain the pin in its current state.
 *
 *          Running the example:
 *              On running the example, the LED on beaglebone would be seen 
 *              turning ON and OFF alternatively.
 *
 */

/*
* Copyright (C) 2010 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 "soc_AM335x.h"
#include "beaglebone.h"
#include "gpio_v2.h"


// Added by Mohit Hada on 05/08/2015 for testing OLED
#include "hw_control_AM335x.h"
#include "hw_cm_wkup.h"
#include "hw_cm_per.h"
#include "hw_types.h"


/*****************************************************************************
**                INTERNAL MACRO DEFINITIONS
*****************************************************************************/
#define GPIO_INSTANCE_ADDRESS           (SOC_GPIO_1_REGS) //modified by Mohit Hada on 05/08/2015
// #define GPIO_INSTANCE_ADDRESS           (SOC_GPIO_2_REGS) // modified by Mohit Hada on 05/08/2015 ofr testing of OLED
#define GPIO_INSTANCE_PIN_NUMBER        (23)

/// Introduced by Mohit Hada on 05/08/2015
#define OSC_CTL                          0x02
#define IREF                             0x80
#define CLOCK_DIV                        0x03
#define REDUCE_CURRENT                   0x04
#define SOFT_RST                         0x05
#define DISP_ON_OFF                      0x06
#define PRECHARGE_TIME_R                 0x08
#define PRECHARGE_TIME_G                 0x09
#define PRECHARGE_TIME_B                 0x0A
#define PRECHARGE_CURRENT_R              0x0B
#define PRECHARGE_CURRENT_G              0x0C
#define PRECHARGE_CURRENT_B              0x0D
#define DRIVING_CURRENT_R                0x10
#define DRIVING_CURRENT_G                0x11
#define DRIVING_CURRENT_B                0x12
#define DISPLAY_MODE_SET                 0x13
#define RGB_IF                           0x14
#define RGB_POL                          0x15
#define MEMORY_WRITE_MODE                0x16
#define MX1_ADDR                         0x17
#define MX2_ADDR                         0x18
#define MY1_ADDR                         0x19
#define MY2_ADDR                         0x1A
#define MEM_PTR_X                        0x20
#define MEM_PTR_Y                        0x21
#define DDRAM_DATA_ACCESS_PORT           0x22
#define GRAY_SCALE_TABLE_INDEX           0x50
#define GRAY_SCALE_TABLE_DATA            0x51
#define DUTY                             0x28
#define DSL                              0x29
#define D1_DDRAM_FAC                     0x2E
#define D1_DDRAM_FAR                     0x2F
#define D2_DDRAM_SAC                     0x31
#define D2_DDRAM_SAR                     0x32
#define SCR1_FX1                         0x33
#define SCR1_FX2                         0x34
#define SCR1_FY1                         0x35
#define SCR1_FY2                         0x36
#define SCR2_SX1                         0x37
#define SCR2_SX2                         0x38
#define SCR2_SY1                         0x39
#define SCR2_SY2                         0x3A
#define SCREEN_SAVER_CONTROL             0x3B
#define SS_SLEEP_TIMER                   0x3C
#define SCREEN_SAVER_MODE                0x3D
#define SS_SCR1_FU                       0x3E
#define SS_SCR1_MXY                      0x3F
#define SS_SCR2_FU                       0x40
#define SS_SCR2_MXY                      0x41
#define MOVING_DIRECTION                 0x42
#define SS_SCR2_SX1                      0x47
#define SS_SCR2_SX2                      0x48
#define SS_SCR2_SY1                      0x49
#define SS_SCR2_SY2                      0x4A
#define FIN                              0xFF
/////////////////////////////////////////////////////////////////////////////

/*****************************************************************************
**                INTERNAL FUNCTION PROTOTYPES
*****************************************************************************/
static void Delay(unsigned int count);
void GPIO2ModuleClkConfig(void);
void GPIO2PinMuxSetup(void);
void oled_powerup(void);
void write_param(unsigned char addr, unsigned char val);
void write_idx(unsigned char v);
void write_ctrl(unsigned char v);
void rect_fill(unsigned char x, unsigned char y, unsigned char dx, unsigned char dy,
             unsigned int lcol, unsigned int fcol);
void write_16(unsigned short int v);
//void GPIO1ModuleClkConfig(void);
/******************************************************************************
**                      TYPE DEF DEFINED FOR OLED   by MOHIT HADA on 05/08/2015 for testing OLED
******************************************************************************/
typedef struct av_s
{
	unsigned char addr;
	unsigned char val;
} av_t;

/********************************************************************************
 ** GLOBAL VARIABLES
 ********************************************************************************/

const av_t oled_init_arr[]=
{
	{DISP_ON_OFF,0},
	{OSC_CTL,1},
	{CLOCK_DIV, 0x30},
	{REDUCE_CURRENT, 0},
	{IREF, 0},
	{PRECHARGE_TIME_R, 1},
	{PRECHARGE_TIME_G, 1},
	{PRECHARGE_TIME_B, 1},
	{PRECHARGE_CURRENT_R, 0x0c},
	{PRECHARGE_CURRENT_G, 0x19},
	{PRECHARGE_CURRENT_B, 0x15},
	{DRIVING_CURRENT_R, 0x32},
	{DRIVING_CURRENT_G, 0x27},
	{DRIVING_CURRENT_B, 0x2b},
	{DISPLAY_MODE_SET, 0},
	{RGB_IF, 0x11},
	{RGB_POL,0},
	{MEMORY_WRITE_MODE, 0x26}, /*76*/ // TODO: We need to check as to whether this is correct or not
	{MX1_ADDR, 0},
	{MX2_ADDR, 0x9f},
	{MY1_ADDR, 0},
	{MY2_ADDR, 0x7f},
	{MEM_PTR_X, 0},
	{MEM_PTR_Y, 0},
	{DUTY, 0x7f},
	{DSL, 0},
	{D1_DDRAM_FAC, 0},
	{D1_DDRAM_FAR, 0},
	{D2_DDRAM_SAC, 0},
	{D2_DDRAM_SAR, 0},
	{SCR1_FX1, 0},
	{SCR1_FX2, 0x9f},
	{SCR1_FY1, 0},
	{SCR1_FY2, 0x7f},
	{FIN, FIN}
};



/*****************************************************************************
**                INTERNAL FUNCTION DEFINITIONS
*****************************************************************************/
/*
** The main function. Application starts here.
*/
int main()
{
	volatile unsigned int i = 0;

    /* Enabling functional clocks for GPIO1 instance. */
    GPIO1ModuleClkConfig();

    /* Selecting GPIO1[23] pin for use. */
    GPIO1Pin23PinMuxSetup();

    /* Enabling the GPIO module. */
    GPIOModuleEnable(GPIO_INSTANCE_ADDRESS);

    /* Resetting the GPIO module. */
    GPIOModuleReset(GPIO_INSTANCE_ADDRESS);

    /* Setting the GPIO pin as an output pin. */
    GPIODirModeSet(GPIO_INSTANCE_ADDRESS,
                   GPIO_INSTANCE_PIN_NUMBER,
                   GPIO_DIR_OUTPUT);
    while(1)
    {
        /* Driving a logic HIGH on the GPIO pin. */
        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                     GPIO_INSTANCE_PIN_NUMBER,
                     GPIO_PIN_HIGH);

        Delay(0x3FFFF);

        /* Driving a logic LOW on the GPIO pin. */
        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                     GPIO_INSTANCE_PIN_NUMBER,
                     GPIO_PIN_LOW);

        Delay(0x3FFFF);
    }

////  LCD_DATA10 on BBB  - GPIO2 - 16 - TO BE USED AS RESET
////	LCD_DATA9  on BBB  - GPIO2 - 15 - TO BE USED HV_EN
//// 	LCD_DATA7  on BBB  - GPIO2 - 13 - TO BE USED CS_B
////  LCD_DATA5  on BBB  - GPIO2 - 11 - TO BE USED RS
////  LCD_DATA3  on BBB  - GPIO2 - 9  - TO BE USED SDO
////  LCD_DATA1  on BBB  - GPIO2 - 7  - TO BE USED SCL
//
//	    /* Enabling functional clocks for GPIO1 instance. */
////	    GPIO2ModuleClkConfig();
//
//
//	// These changes are done just to check the eMMC interface
//	///////////////////////////////////////////////////////////////////////////////////
//	    GPIO1ModuleClkConfig();
//
//		Delay(0x1FFF);
//
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(0)) = CONTROL_CONF_MUXMODE(7);
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(1)) = CONTROL_CONF_MUXMODE(7);
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(2)) = CONTROL_CONF_MUXMODE(7);
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(3)) = CONTROL_CONF_MUXMODE(7);
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(4)) = CONTROL_CONF_MUXMODE(7);
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(5)) = CONTROL_CONF_MUXMODE(7);
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(6)) = CONTROL_CONF_MUXMODE(7);
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(7)) = CONTROL_CONF_MUXMODE(7);
//
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_CSN(1)) = CONTROL_CONF_MUXMODE(7);
//	    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_CSN(2)) = CONTROL_CONF_MUXMODE(7);
//
//		Delay(0x1FFF);
//
//
//		GPIOModuleEnable(0x4804C000); // GPIO-1 Module Enabled
//
//		GPIOModuleReset(0x4804C000);
//
//
////		GPIODirModeSet(0x4804C000,
////					   0,
////					   GPIO_DIR_OUTPUT);
////
////		while(1)
////		{
////		GPIOPinWrite(0x4804C000,
////		             0,
////		            GPIO_PIN_LOW);
////
////		GPIOPinWrite(0x4804C000,
////		             0,
////		            GPIO_PIN_HIGH);
////		}
//
//		for (i=0;i<=9;i++)
//		{
//			if(i==0)
//			{
//				GPIODirModeSet(0x4804C000,
//			                   i,
//			                   GPIO_DIR_OUTPUT);
//			}
//			else if(i<=7)
//			{
//				GPIODirModeSet(0x4804C000,
//			                   i,
//			                   GPIO_DIR_OUTPUT);
//			}
//			else if(i==8)
//			{
//				GPIODirModeSet(0x4804C000,
//			                   30,
//			                   GPIO_DIR_OUTPUT);
//			}
//			else
//			{
//				GPIODirModeSet(0x4804C000,
//			                   31,
//			                   GPIO_DIR_OUTPUT);
//			}
//
//		}
//
//		Delay(0x1FFF);
//
//		while(1)
//		{
//			for (i=0;i<=9;i++)
//			{
//				if(i==0)
//				{
//					GPIOPinWrite(0x4804C000,
//				                   i,
//								   GPIO_PIN_HIGH);
//				}
//				else if(i<=7)
//				{
//					GPIOPinWrite(0x4804C000,
//				                   i,
//								   GPIO_PIN_HIGH);
//				}
//				else if(i==8)
//				{
////					GPIOPinWrite(0x4804C000,
////				                   30,
////								   GPIO_PIN_HIGH);
//				}
//				else
//				{
//					GPIOPinWrite(0x4804C000,
//				                   31,
//								   GPIO_PIN_HIGH);
//				}
//			}
//
//			for (i=0;i<=9;i++)
//			{
//				if(i==0)
//				{
//					GPIOPinWrite(0x4804C000,
//				                   i,
//								   GPIO_PIN_LOW);
//				}
//				else if(i<=7)
//				{
//					GPIOPinWrite(0x4804C000,
//								   i,
//								   GPIO_PIN_LOW);
//				}
//				else if(i==8)
//				{
////					GPIOPinWrite(0x4804C000,
////								   30,
////								   GPIO_PIN_LOW);
//				}
//				else
//				{
//					GPIOPinWrite(0x4804C000,
//								   31,
//								   GPIO_PIN_LOW);
//				}
//			}
//
//			}
//
//
//
//
//		//////////////////////////////////////////////////////////////////////////////////////
//
////	    /* Selecting GPIO2[16,15,13,11,9 and 7] pin for use. */
////	    GPIO2PinMuxSetup();   // to be checked...
////
////	    /* Enabling the GPIO module. */
////	    GPIOModuleEnable(GPIO_INSTANCE_ADDRESS);
////
////	    /* Resetting the GPIO module. */
////	    GPIOModuleReset(GPIO_INSTANCE_ADDRESS);
////
////	    /* Setting the GPIO2 PIN -16  pin as an output pin. */
////	    GPIODirModeSet(GPIO_INSTANCE_ADDRESS,
////	                   16,
////	                   GPIO_DIR_OUTPUT);
////	    /* Setting the GPIO2 PIN -15  pin as an output pin. */
////	    GPIODirModeSet(GPIO_INSTANCE_ADDRESS,
////	                   15,
////	                   GPIO_DIR_OUTPUT);
////	    /* Setting the GPIO2 PIN -13  pin as an output pin. */
////	    GPIODirModeSet(GPIO_INSTANCE_ADDRESS,
////	                   13,
////	                   GPIO_DIR_OUTPUT);
////	    /* Setting the GPIO2 PIN -11  pin as an output pin. */
////	    GPIODirModeSet(GPIO_INSTANCE_ADDRESS,
////	                   11,
////	                   GPIO_DIR_OUTPUT);
////	    /* Setting the GPIO2 PIN -9  pin as an output pin. */
////	    GPIODirModeSet(GPIO_INSTANCE_ADDRESS,
////	                   9,
////	                   GPIO_DIR_OUTPUT);
////	    /* Setting the GPIO2 PIN -7  pin as an output pin. */
////	    GPIODirModeSet(GPIO_INSTANCE_ADDRESS,
////	                   7,
////	                   GPIO_DIR_OUTPUT);
////
//////******************Initial State of OLED Pins***********************////
////
////        /* PUT OLED IN RESET STATE */
////        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
////                     16,
////                     GPIO_PIN_LOW);
////        /* DISABLE HV. */
////        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
////                     15,
////                     GPIO_PIN_LOW);
////        /* Driving a logic HIGH on the CS pin. */
////        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
////                     13,
////                     GPIO_PIN_HIGH);
////        /* Driving a logic HIGH on the RS pin. */
////        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
////                     11,
////                     GPIO_PIN_HIGH);
////        /* Driving a logic HIGH on the SDO pin. */
////        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
////                     9,
////                     GPIO_PIN_LOW);
////        /* Driving a logic HIGH on the SCL pin. */
////        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
////                     7,
////                     GPIO_PIN_LOW);
////
////        Delay(0x3FFFF);
////
////        /* PUT OLED OUT OF RESET STATE */
////         GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
////                      16,
////                      GPIO_PIN_HIGH);
////
////     	oled_powerup(); // configures the OLED, and powers it up



} 

/*
** A function which is used to generate a delay.
*/
static void Delay(volatile unsigned int count)
{
    while(count--);
}


void GPIO2ModuleClkConfig(void)
{

    /* Writing to MODULEMODE field of CM_PER_GPIO2_CLKCTRL register. */
    HWREG(SOC_CM_PER_REGS + CM_PER_GPIO2_CLKCTRL) |=
          CM_PER_GPIO2_CLKCTRL_MODULEMODE_ENABLE;

    /* Waiting for MODULEMODE field to reflect the written value. */
    while(CM_PER_GPIO2_CLKCTRL_MODULEMODE_ENABLE !=
          (HWREG(SOC_CM_PER_REGS + CM_PER_GPIO2_CLKCTRL) &
           CM_PER_GPIO2_CLKCTRL_MODULEMODE));
    /*
    ** Writing to OPTFCLKEN_GPIO_2_GDBCLK bit in CM_PER_GPIO2_CLKCTRL
    ** register.
    */
    HWREG(SOC_CM_PER_REGS + CM_PER_GPIO2_CLKCTRL) |=
          CM_PER_GPIO2_CLKCTRL_OPTFCLKEN_GPIO_2_GDBCLK;

    /*
    ** Waiting for OPTFCLKEN_GPIO_2_GDBCLK bit to reflect the desired
    ** value.
    */
    while(CM_PER_GPIO2_CLKCTRL_OPTFCLKEN_GPIO_2_GDBCLK !=
          (HWREG(SOC_CM_PER_REGS + CM_PER_GPIO2_CLKCTRL) &
           CM_PER_GPIO2_CLKCTRL_OPTFCLKEN_GPIO_2_GDBCLK));

    /*
    ** Waiting for IDLEST field in CM_PER_GPIO2_CLKCTRL register to attain the
    ** desired value.
    */
    while((CM_PER_GPIO2_CLKCTRL_IDLEST_FUNC <<
           CM_PER_GPIO2_CLKCTRL_IDLEST_SHIFT) !=
           (HWREG(SOC_CM_PER_REGS + CM_PER_GPIO2_CLKCTRL) &
            CM_PER_GPIO2_CLKCTRL_IDLEST));

    /*
    ** Waiting for CLKACTIVITY_GPIO_2_GDBCLK bit in CM_PER_L4LS_CLKSTCTRL
    ** register to attain desired value.
    */
    while(CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_GPIO_2_GDBCLK !=
          (HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKSTCTRL) &
           CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_GPIO_2_GDBCLK));
}


//void GPIO1ModuleClkConfig(void)
//{
//
//    /* Writing to MODULEMODE field of CM_PER_GPIO2_CLKCTRL register. */
//    HWREG(SOC_CM_PER_REGS + CM_PER_GPIO1_CLKCTRL) |=
//          CM_PER_GPIO1_CLKCTRL_MODULEMODE_ENABLE;
//
//    /* Waiting for MODULEMODE field to reflect the written value. */
//    while(CM_PER_GPIO1_CLKCTRL_MODULEMODE_ENABLE !=
//          (HWREG(SOC_CM_PER_REGS + CM_PER_GPIO1_CLKCTRL) &
//           CM_PER_GPIO1_CLKCTRL_MODULEMODE));
//    /*
//    ** Writing to OPTFCLKEN_GPIO_1_GDBCLK bit in CM_PER_GPIO1_CLKCTRL
//    ** register.
//    */
//    HWREG(SOC_CM_PER_REGS + CM_PER_GPIO1_CLKCTRL) |=
//          CM_PER_GPIO1_CLKCTRL_OPTFCLKEN_GPIO_1_GDBCLK;
//
//    /*
//    ** Waiting for OPTFCLKEN_GPIO_1_GDBCLK bit to reflect the desired
//    ** value.
//    */
//    while(CM_PER_GPIO1_CLKCTRL_OPTFCLKEN_GPIO_1_GDBCLK !=
//          (HWREG(SOC_CM_PER_REGS + CM_PER_GPIO1_CLKCTRL) &
//           CM_PER_GPIO1_CLKCTRL_OPTFCLKEN_GPIO_1_GDBCLK));
//
//    /*
//    ** Waiting for IDLEST field in CM_PER_GPIO1_CLKCTRL register to attain the
//    ** desired value.
//    */
//    while((CM_PER_GPIO1_CLKCTRL_IDLEST_FUNC <<
//           CM_PER_GPIO1_CLKCTRL_IDLEST_SHIFT) !=
//           (HWREG(SOC_CM_PER_REGS + CM_PER_GPIO1_CLKCTRL) &
//            CM_PER_GPIO1_CLKCTRL_IDLEST));
//
//    /*
//    ** Waiting for CLKACTIVITY_GPIO_1_GDBCLK bit in CM_PER_L4LS_CLKSTCTRL
//    ** register to attain desired value.
//    */
//    while(CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_GPIO_1_GDBCLK !=
//          (HWREG(SOC_CM_PER_REGS + CM_PER_L4LS_CLKSTCTRL) &
//           CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_GPIO_1_GDBCLK));
//}

void GPIO2PinMuxSetup(void)
{
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(10)) = CONTROL_CONF_MUXMODE(7);
	HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(9))  = CONTROL_CONF_MUXMODE(7);
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(7))  = CONTROL_CONF_MUXMODE(7);
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(5))  = CONTROL_CONF_MUXMODE(7);
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(3))  = CONTROL_CONF_MUXMODE(7);
    HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(1))  = CONTROL_CONF_MUXMODE(7);

}

// This configures the display, applies the high voltage and enables the display
void oled_powerup(void)
{
	int i=0;
	int not_finished=1;
	unsigned char addr, val;
	while(not_finished)
	{
		addr=oled_init_arr[i].addr;
		val=oled_init_arr[i].val;
		if ((addr==FIN) && (val==FIN))
		{
			not_finished=0;
			break;
		}
		write_param(addr, val);
		i++;
	}

	/* ENABLE HV. */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 15,
                 GPIO_PIN_HIGH);

    Delay(0x3FFFF);

	rect_fill(0, 0, 160, 128, 0x0000, 0x0000); // clear to blank screen

	write_param(DISP_ON_OFF, 1);

    Delay(0x0FFFF);

}

// Use this to write an instruction to the display
void write_param(unsigned char addr, unsigned char val)
{
	//if (display_dbg) printf("addr=0x%02x, val=0x%02x\n", addr, val);
	write_idx(addr);
	write_ctrl(val);
}

void write_idx(unsigned char v)
{
	int i;
	unsigned char ibyte;
//	RS_LOW;
//	CS_LOW;
//	SCL_LOW;

   /* RS LOW FOR COMMAND TRANSFER */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 11,
				 GPIO_PIN_LOW);
    /* CS LOW FOR SPI INTERFACE */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 13,
				 GPIO_PIN_LOW);
    /* Driving a logic LOW on the SCL pin. */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 7,
				 GPIO_PIN_LOW);

	ibyte=v;
	// transmit instruction byte
	for (i=0; i<8; i++)
	{
		if (ibyte & 0x80) // If MSB of data is '1' // TODO: we need to check whether such comparison can be done or not
		{
	        //SDO HIGH
	        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
	                     9,
						 GPIO_PIN_HIGH);
		}
		else
		{
	        //SDO LOW
	        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
	                     9,
						 GPIO_PIN_LOW);
		}
		ibyte=ibyte<<1; // Left Shift the command data

	    /* CLOCK HIGH THE COMMAND BIT */
	    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
	                 7,
					 GPIO_PIN_HIGH);
		if (i<7)	// on last bit, don't pull SCL low
		{
		    /* CLOCK LOW. */
		    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
		                 7,
						 GPIO_PIN_LOW);
		}
	}
    /* RS HIGH AFTER COMMAND TRANSFER */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 11,
				 GPIO_PIN_HIGH);
    /* CS HIGH AFTER SPI INTERFACE */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 13,
				 GPIO_PIN_HIGH);

//	RS_HIGH;
//	CS_HIGH;
  }


void write_ctrl(unsigned char v)
{
	int i;
	unsigned char ibyte;
//	RS_HIGH;
//	CS_LOW;
//	SCL_LOW;

   /* RS HIGH FOR DATA TRANSFER */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 11,
				 GPIO_PIN_HIGH);
    /* CS LOW FOR SPI INTERFACE */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 13,
				 GPIO_PIN_LOW);
    /* Driving a logic LOW on the SCL pin. */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 7,
				 GPIO_PIN_LOW);

	ibyte=v;
	// transmit instruction byte
	for (i=0; i<8; i++)
	{
		if (ibyte & 0x80) // If MSB of data is '1'  // TODO: we need to check whether such comparison can be done or not
		{
	        //SDO HIGH
	        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
	                     9,
						 GPIO_PIN_HIGH);
		}
		else
		{
	        //SDO LOW
	        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
	                     9,
						 GPIO_PIN_LOW);
		}
		ibyte=ibyte<<1; // Left Shift the data

	    /* CLOCK HIGH THE COMMAND BIT */
	    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
	                 7,
					 GPIO_PIN_HIGH);
		if (i<7)	// on last bit, don't pull SCL low
		{
		    /* CLOCK LOW. */
		    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
		                 7,
						 GPIO_PIN_LOW);
		}
	}
    /* RS HIGH AFTER DATA TRANSFER */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 11,
				 GPIO_PIN_HIGH);
    /* CS HIGH AFTER SPI INTERFACE */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 13,
				 GPIO_PIN_HIGH);

//	RS_HIGH;
//	CS_HIGH;
  }

void
rect_fill(unsigned char x, unsigned char y, unsigned char dx, unsigned char dy,
             unsigned int lcol, unsigned int fcol)
{
	int i, xx, yy;
	write_param(MX1_ADDR, x);
	write_param(MX2_ADDR, x+dx-1);
	write_param(MY1_ADDR, 128-y-dy);
	write_param(MY2_ADDR, 127-y);

	write_param(MEM_PTR_X, x);
	write_param(MEM_PTR_Y, 128-y-dy);
	write_idx(DDRAM_DATA_ACCESS_PORT);
	if (lcol==fcol)  // TODO: we need to check whether such comparison can be done or not
	{
		for (i=0; i<(dx*dy); i++)
		{
			write_16(fcol);
		}
	}
	else
	{
		for (yy=0; yy<dy; yy++)
		{
			for (xx=0; xx<dx; xx++)
			{
				if ((xx==0) || (xx==dx-1) || (yy==0) || (yy==dy-1))
				{
					write_16(lcol);
				}
				else
				{
					write_16(fcol);
				}
			}
		}
	}
}
// This writes a 16-bit RGB565 value to the display
void write_16(unsigned short int v)
{
	int i, j;
	unsigned char* vptr;
	unsigned char ibyte[2];
//	RS_HIGH;
//	CS_LOW;
//	SCL_LOW;

   /* RS HIGH FOR DATA TRANSFER */
	GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
				 11,
				 GPIO_PIN_HIGH);
	/* CS LOW FOR SPI INTERFACE */
	GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
				 13,
				 GPIO_PIN_LOW);
	/* Driving a logic LOW on the SCL pin. */
	GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
				 7,
				 GPIO_PIN_LOW);

	vptr=(unsigned char*)&v;
	ibyte[1]=*vptr;
	ibyte[0]=*(vptr+1);

	for (j=0; j<2; j++)
	{
		// transmit instruction byte
		for (i=0; i<8; i++)
		{
			if (ibyte[j] & 0x80) // if MSB = '1', TODO: We have to check whether such comparisons are allowed or not...
			{
		        //SDO HIGH
		        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
		                     9,
							 GPIO_PIN_HIGH);
			}
			else
			{
		        //SDO LOW
		        GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
		                     9,
							 GPIO_PIN_LOW);
			}
			ibyte[j]=ibyte[j]<<1;
		    /* CLOCK HIGH THE COMMAND BIT */
		    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
		                 7,
						 GPIO_PIN_HIGH);
		    /* CLOCK LOW. */
		    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
		                 7,
						 GPIO_PIN_LOW);
		}
	}

   /* RS HIGH AFTER DATA TRANSFER */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 11,
				 GPIO_PIN_HIGH);
    /* CS HIGH AFTER SPI INTERFACE */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 13,
				 GPIO_PIN_HIGH);
    /* CLOCK HIGH THE COMMAND BIT */
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS,
                 7,
				 GPIO_PIN_HIGH);

//	SCL_HIGH;
//	RS_HIGH;
//	CS_HIGH;
}

/******************************* End of file *********************************/
