/*****************************************************************************
 * Microchip Graphics Library Demo Application
 * This program shows how to use the Graphics Objects Layer.
 *****************************************************************************
 * FileName:        AN1136Demo.c
 * Dependencies:    AN1136Demo.h
 * Processor:       PIC24
 * Compiler:       	MPLAB C30 V3.00
 * Linker:          MPLAB LINK30
 * Company:         Microchip Technology Incorporated
 *
 * Software License Agreement
 *
 * Copyright ?2007 Microchip Technology Inc.  All rights reserved.
 * Microchip licenses to you the right to use, modify, copy and distribute
 * Software only when embedded on a Microchip microcontroller or digital
 * signal controller, which is integrated into your product or third party
 * product (pursuant to the sublicense terms in the accompanying license
 * agreement).  
 *
 * You should refer to the license agreement accompanying this Software
 * for additional information regarding your rights and obligations.
 *
 * SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS?WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
 * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
 * PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR
 * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
 * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
 * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
 * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
 * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
 * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
 * OR OTHER SIMILAR COSTS.
 *
 * Author               Date        Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Paolo A. Tamayo		07/20/07	...
 *****************************************************************************/

/*
******************************************************************************
* This program has been ported to the hardware platform 
* PIC24-Eval-B2 Rev B with a QVGA LCD module TY280T-240320-BO Rev 1B.
* This project demonstrates landscape driver for ILI9325 in 16-bit mode with
* internal ADC of PIC24 to decode touch panel signal.
*
* Connect a straight cable from PC's COM PORT to RS232 connector onboard (J2B) 
* for serial communication. This link is used for user interface testing 
* the NAND Flash.
* First, LCD shows graphics of pure RGB for dead point inspection. 
* Afterwards there will be two buttons (LEFT & RIGHT) and a slide bar being the
* same as that from Graphics AN1136 demonstration originally released by Microchip.
* Two buttons added for NAND Flash demonstration as WR Flash and RD Flash. 
* WR Flash is to show the device ID of NAND Flash on HyperTerminal.
* The baud rate was 19200bps, no parity, 1-stop bit, no handshake.
* Follow instruction on HyperTerminal and input any character you want to write
* to the first block of NAND Flash. RD Flash is for data retrieval from NAND Flash
* and export to HyperTerminal for error check.
*
* Author : John Leung
* Company: TechToys Company
* www.TechToys.com.hk
* Date: 16th June 2008
******************************************************************************
*/

/*
******************************************************************************
* Updated on 3rd Sept for TouchScreen.h and TouchScreen.c
******************************************************************************
*/

#include "AN1136Demo.h"

// Configuration bits
// Configure fast RC oscillator with PLL and RC15 pin for Fosc/2 function	
_CONFIG2(FNOSC_FRCPLL & OSCIOFNC_OFF)
_CONFIG1(JTAGEN_OFF & FWDTEN_OFF)   // JTAG off, watchdog timer off

/////////////////////////////////////////////////////////////////////////////
//                          FOR NAND Flash Demo via UART
/////////////////////////////////////////////////////////////////////////////
void putUART1(INT8U c)
{
	while(U1STAbits.UTXBF);
	U1TXREG = c;
}

INT8U getUART1(void)
{
	while(!U1STAbits.URXDA);
	return U1RXREG;
}


void TickInit(void);                        // Starts tick counter  

/////////////////////////////////////////////////////////////////////////////
//                              OBJECT'S IDs
/////////////////////////////////////////////////////////////////////////////

#define ID_BTN1 	    10
#define ID_BTN2     	11
#define ID_BTN3			12
#define ID_BTN4			13
#define ID_SLD1	    	20

/////////////////////////////////////////////////////////////////////////////
//                            LOCAL PROTOTYPES
/////////////////////////////////////////////////////////////////////////////
void CheckCalibration(void);            // check if calibration is needed

/////////////////////////////////////////////////////////////////////////////
//                            IMAGES USED
/////////////////////////////////////////////////////////////////////////////
extern BITMAP_FLASH redRightArrow;
extern BITMAP_FLASH redLeftArrow;

/////////////////////////////////////////////////////////////////////////////
//                                  MAIN
/////////////////////////////////////////////////////////////////////////////
GOL_SCHEME	*altScheme;                 // alternative style scheme
SLIDER 		*pSld;					    // pointer to the slider object
WORD    	update = 0;				    // variable to update customized graphics

unsigned int DeviceID;
int j;
unsigned char dataInput, dataBuffer[NAND_PAGE_SIZE_BYTE];;


int main(void){

	int x,y;

	CLKDIV = 0x0000;					//FRC postscaler divided by 1 (8MHz from internal RC)

	U1BRG     = 207;					//uart baud rate of 19200bps
    U1MODE    = 0x8008;					//enable uart, BRGH=1, 1 stop bit with no parity
	U1STA     = 0x0400; 				//enable transmission, clear all flags

	GOL_MSG msg;        				// GOL message structure to interact with GOL

    EEPROMInit();   					// initialize EEPROM
    TouchInit();    					// initialize touch screen

    GOLInit();      					// initialize graphics library & 
  										// create default style scheme for GOL
	CheckCalibration();

	SetColor(BRIGHTRED);
	ClearDevice();
	DelayMs(2000);
	SetColor(BRIGHTGREEN);
	ClearDevice();
	DelayMs(2000);
	SetColor(BRIGHTBLUE);
	ClearDevice();
	DelayMs(2000);
	SetColor(WHITE);
	ClearDevice();
	DelayMs(2000);
	SetColor(BLACK);
	ClearDevice();	

    altScheme = GOLCreateScheme(); 		// create alternative style scheme
    altScheme->TextColor0 = BLACK;
    altScheme->TextColor1 = BRIGHTBLUE;

	BtnCreate(	ID_BTN1,	 			// object’s ID
				20, 110, 150, 160,		// object’s dimension
                0,                      // radius of the rounded edge
				BTN_DRAW,				// draw the object after creation
				NULL,					// no bitmap used
				"LEFT",					// use this text
				altScheme);				// use alternative style scheme

	BtnCreate(	ID_BTN2, 
				170, 110, 300, 160,
                0,
				BTN_DRAW,
				NULL,
				"RIGHT",
				altScheme);

	BtnCreate(	ID_BTN3, 
				20, 170, 150, 220,
                0,
				BTN_DRAW,
				NULL,
				"WR Flash",
				altScheme);

	BtnCreate(	ID_BTN4, 
				170, 170, 300, 220,
                0,
				BTN_DRAW,
				NULL,
				"RD Flash",
				altScheme);

	pSld = SldCreate(ID_SLD1,		    // object’s ID
				20, 55, 300, 100,		// object’s dimension
				SLD_DRAW,				// draw the object after creation
				100,					// range
				5,						// page 
				50,						// initial position
				NULL);					// use default style scheme
		
	update = 1;							// to initialize the user graphics

	while(1){

        if (GOLDraw()) {				// Draw GOL object
        	TouchGetMsg(&msg);   		// Get message from touch screen
        	GOLMsg(&msg);        		// Process message
        }	

    } 

}

/////////////////////////////////////////////////////////////////////////////
// Function: WORD GOLMsgCallback(WORD objMsg, OBJ_HEADER* pObj, GOL_MSG* pMsg)
// Input: objMsg - translated message for the object,
//        pObj - pointer to the object,
//        pMsg - pointer to the non-translated, raw GOL message 
// Output: if the function returns non-zero the message will be processed by default
// Overview: it's a user defined function. GOLMsg() function calls it each
//           time the valid message for the object received
/////////////////////////////////////////////////////////////////////////////
WORD GOLMsgCallback(WORD objMsg, OBJ_HEADER* pObj, GOL_MSG* pMsg){
	WORD objectID;
	SLIDER *pSldObj;
	
    objectID = GetObjID(pObj);
	
	if (objectID == ID_BTN1) {							// LEFT button pressed 
		if (objMsg == BTN_MSG_PRESSED) {				// check if button is pressed

 			BtnSetBitmap(pObj, &redLeftArrow);          // set bitmap to show
			SetState(pObj, BTN_TEXTRIGHT);				// move the text to the right

 			pSldObj = (SLIDER*)GOLFindObject(ID_SLD1);	// find slider pointer
			SldDecPos(pSldObj);							// decrement the slider position
			SetState(pSldObj, SLD_DRAW_THUMB);			// redraw only the thumb
		}
		else {
			 BtnSetBitmap(pObj, NULL);					// remove the bitmap
			 ClrState(pObj, BTN_TEXTRIGHT);				// place the text back in the middle
		}
		update = 1;
	}

	if (objectID == ID_BTN2) {
		if (objMsg == BTN_MSG_PRESSED) {
			
 			BtnSetBitmap(pObj, &redRightArrow);    		// set bitmap to show         
			SetState(pObj, BTN_TEXTLEFT);				// move the text to the left

			pSldObj = (SLIDER*)GOLFindObject(ID_SLD1);	// find slider pointer
			SldIncPos(pSldObj);							// increment the slider position
			SetState(pSldObj, SLD_DRAW_THUMB);			// redraw only the thumb
		}
		else {
			 BtnSetBitmap(pObj, NULL);					// remove the bitmap
			 ClrState(pObj, BTN_TEXTLEFT);				// place the text back in the middle
		}
		update = 1;
	}
	
	if (objectID == ID_BTN3) {
		if (objMsg == BTN_MSG_PRESSED) {
				nandInit();					//initialize NAND Flash here
				DeviceID = nandChkID();
				printf("DeviceID for your nandFlash is : %X\r\n",DeviceID); 
				nandEraseBlk(0);
				printf("Block erase complete\r\n");
				printf("Please input the character to be written:\r\n");
				dataInput=getUART1();
				printf("You are writing '%c' to nand Flash page\r\n", dataInput);
				for(j=0;j<NAND_PAGE_SIZE_BYTE;j++) dataBuffer[j]=dataInput;
				nandWrPage(0,0, 0, &dataBuffer[0]);		
				printf("Write complete\r\n");	
		}
		update = 1;
	}

	if (objectID == ID_BTN4) {
		if (objMsg == BTN_MSG_PRESSED) {
				nandInit();					//initialize NAND Flash here
				for(j=0;j<NAND_PAGE_SIZE_BYTE;j++) dataBuffer[j]=0x00;	
				nandRdPage(0,0, 0, &dataBuffer[0]);
				for(j=0;j<NAND_PAGE_SIZE_BYTE;j++) 
					{	printf("Data at %u: %c\r\n", j, dataBuffer[j]);	
						DelayMs(5);
					}
		}
		update = 1;
	}


	if (objectID == ID_SLD1) {
		if ((objMsg == SLD_MSG_INC) || (objMsg == SLD_MSG_DEC)) {
			update = 1;
		}
	}
	return 1;
}

/////////////////////////////////////////////////////////////////////////////
// Function: WORD GOLDrawCallback()
// Output: if the function returns non-zero the draw control will be passed to GOL
// Overview: it's a user defined function. GOLDraw() function calls it each
//           time when GOL objects drawing is completed. User drawing should be done here.
//           GOL will not change color, line type and clipping region settings while 
//           this function returns zero.
/////////////////////////////////////////////////////////////////////////////
WORD GOLDrawCallback(){

WORD value, y, x;							// variables for the slider position
static WORD prevValue = 0;

	if (update) {
		/* User defined graphics:	
		    This draws a series of bars indicating the value/position of the 
			slider's thumb. The height of the bars follows the equation of a 
			parabola "(y-k)^2 = 4a(x-h) with vertex at (k, h) at (60,55) on 
			the display. The value 220 is the 4*a constant. x & y are calculated
			based on the value of the slider thumb. The bars are drawn from 
			60 to 260 in the x-axis and 10 to 55 in the y-axis.
			
			Only the bars that are added or removed are drawn. Thus resulting 
			in an efficient customized drawing. 
		*/	
		// check the value of slider
		value = SldGetPos(pSld);

		// remove bars if there the new value is less 
		// than the previous
		SetColor(BLACK) 
		if (value < prevValue) {
			while (prevValue > value) {
				// get the height of the bar to be removed
				y = (prevValue*prevValue)/220;

				// bars are drawn every 6 pixels with width = 4 pixels.
				x = (prevValue*2);
				x = x - (x%6);

				// draw a BLACK colored bar to remove the current bar drawn
				Bar(x+60,50-y, x+64,50);
				// decrement by three since we are drawing every 6 pixels
				prevValue -= 3;
			}
		}
		// Draw bars if there the new value is greater 
		// than the previous
		else {
			while (prevValue < value) {
				if (prevValue < 60) {
					SetColor(BRIGHTGREEN); 	
				} else if ((prevValue < 80) && (prevValue >= 60)) {
					SetColor(BRIGHTYELLOW); 	
				} else if (prevValue >= 80) {
					SetColor(BRIGHTRED); 	
				}
				// get the height of the bar to be drawn
				y = (prevValue*prevValue)/220;

				// bars are drawn every 6 pixels with width = 4 pixels.
				x = (prevValue*2);
				x = x - (x%6);

				// draw a bar to increase in value
				Bar(x+60,50-y, x+64,50);
				// increment by three since we are drawing every 6 pixels
				prevValue += 3;
			}
		}
		// prevValue will have the current value after drawing or removing bars.
		// reset the update flag
		update = 0;
	}

    return 1; 				
}

void CheckCalibration(void)                  // Check if calibration is needed
{
    // If KEY 1 button on PIC24-Eval-B2 board is pressed calibrate touch screen
		TRISAbits.TRISA14 = 1;						//RA14 as an input
		TRISAbits.TRISA2 = 0; LATAbits.LATA2 = 0;	//RA2 as an output low

		if(PORTAbits.RA14 == 0){
        TouchCalibration();
        TouchStoreCalibration();
    }

    // If it's a new board (version byte in EEPROM has different value) calibrate touch screen
    if(GRAPHICS_LIBRARY_VERSION != EEPROMReadWord(EEPROM_VERSION)){
        TouchCalibration();
        TouchStoreCalibration();
        EEPROMWriteWord(GRAPHICS_LIBRARY_VERSION,EEPROM_VERSION);
    }

    // Load touch screen calibration parameters from EEPROM
    TouchLoadCalibration();
	
}

