/*
******************************************************************************************************
* Program description: 	This is a demo program to access SSD1963 in 16-bit 8080 addressing mode.
* 						No complex functions, no GUI, no touch panel, but the basic IO command for
*						addressing SSD1963 is provided here.
*						Although the Microchip Graphics Library has been employed intensively throughout our
*						list of examples, it is not restricted to use Microchip.
*						Any microcontroller or processor that is able to generate the required control
*						signal (CS#, DC, RD#, WR#, and D[23:0]) will be able to drive SSD1963.
*						User may refer to the original application note released by Solomon Systech at Doc 04
*						under this hyperlink to download the document.
*						http://www.techtoys.com.hk/Displays/SSD1963EvalRev3B/SSD1963%20Eval%20Board%20Rev3B.htm
*
*						I sincerely hope this program is able to serve as the starting point
*						for porting SSD1963 driver to your own platform.
*
* How to use this demo:	(1) Define the hardware platform from system.h file
*							comment one of the following sentances to define either PIC24/32 EVK RD4
*							or MMEVK R1A
*							#define PIC32_STARTER_KIT
*							//#define PIC32MX_EVK_RD4
*						(2) Define the TFT panel to use.
*							Under TFT.h, select only one of the TFT panels available from us.
*							#define DISPLAY_PANEL TY430TFT480272
*							//#define DISPLAY_PANEL TY500TFT800480
*							//#define DISPLAY_PANEL TY700TFT800480
*							//#define DISPLAY_PANEL YOUR_PANEL
*						(3) Finally, rebuild the project.
*
* FileName:				MainDemo.c
* Hardware:				(1) PIC24/32 EVK RD4 with PIC32MX360F512L MCU option -or-
*						Multimedia Evaluation platform for PIC32SK (MMEVK R1A)
*						(2) SSD1963EVK R3B
*						(3) 4.3", 5", or 7" TFT panels
* Compiler:        		Microchip C32 v1.12 or above, MPLAB v8.63
* Programmer:			John Leung
* Company:				www.TechToys.com.hk
* Date:					20th June 2011
******************************************************************************************************
*/

/*
 *****************************************************************************
 * Revision
 * by John Leung of TechToys Co. (www.TechToys.com.hk)
 *
 * Date: 28th June 2012
 * 1. 	Add support for 8-bit interface with PIC18F24J10-I/SP
 * 		#if defined (__18CXX)
 * 2. Add support for new 7" TFT model: TY700TFT800480_R3
 * 3. Add support for SSD1963 EVK Ultima Rev4.1
 *****************************************************************************
*/
#include "SSD1963.h"
#include "system.h"
#include "TimeDelay.h" 
#include <math.h>		//for fabs() in DrawLine()

#if defined (__18CXX)
//PIC18F24J10 28 pin (PDIP) MCU of 16Kbytes Flash 1024 Bytes Memory
//A ow pin count MCU just to demonstrate the kit is working
//Operating Frequency of PIC18F2J10 ranges from DC-40MHz
//Configuration bits setting from C:\MCC18\doc\hlpPIC18ConfigSet.html
//The path can be different from your working environment
	#pragma config DEBUG = ON		//use ICD2/3 as debugger
    #pragma config XINST = OFF		//instruction set extension off
    #pragma config STVREN = ON		//reset on stack overflow
    #pragma config WDTEN = OFF		//disable watchdog
    #pragma config CP0 = OFF		//code-protected off	
    #pragma config FCMEN = OFF		//fail-safe clock monitor disabled
	#pragma config IESO = ON		//two-speed start-up enabled
    #pragma config FOSC2 = ON		//clock selected by FOSC as system clock enabled when OSCCON<1:0> = 00
    #pragma config FOSC = HSPLL		//HS mode with iwht 4x PLL ON


#elif defined (__PIC32MX__)
// Configuration Bit settings
// SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)
// PBCLK = 80 MHz
// Primary Osc w/PLL (XT+,HS+,EC+PLL)
// WDT OFF
// Other options are don't care
	#if defined (PIC32_STARTER_KIT)
	#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2	//because it is 8MHz builtin PIC32_STARTER_KIT
	#elif defined (PIC32MX_EVK_RD4)
	#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_3	//because it is 12MHz builtin PIC24/32 EVK RD4
	#endif
	#pragma config FPLLODIV = DIV_1, FWDTEN = OFF
	#pragma config POSCMOD = HS, FNOSC = PRIPLL
#endif

/*
**********************************************************************************************************
* A random generator from 
* http://www.daniweb.com/software-development/c/code/216329/construct-your-own-random-number-generator
**********************************************************************************************************
*/
unsigned int 	rand1(int lim);
/*
**********************************************************************************************************
* Line draw function from Programming The Nintendo Game Boy Advance: The Unofficial Guide
* Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
**********************************************************************************************************
*/
void			DrawLine(int x1, int y1, int x2, int y2, int _color);

//////////////////////////////////////// MAIN ///////////////////////////////////////////////////////////
#if defined (__18CXX)
	void main (void)
#elif defined (__PIC32MX__)
	int main(void)
#endif

{
	unsigned int x1, y1, x2, y2, counter;

	
	#if defined (PIC32MX_EVK_RD4)
		DDPCONbits.JTAGEN = 0;	//disable the JTAG port
	#elif defined (PIC32_STARTER_KIT)
		DDPCONbits.JTAGEN = 1;	//enable the JTAG port
	#endif

	#if defined (__18CXX)
		ADCON1 = 0x0F;							//all digital
	#endif
	/*
	Configure the device for maximum performance.
	This macro sets flash wait states, PBCLK divider and DRM wait states
	based on the specified clock frequency. It also turns on the cache
	mode if avaialble.
	Based on the current frequency, the PBCLK divider will be set at 1:1.
	This knowledge is required0 to correctly set UART baud rate, timer
	reload value and other time sensitive setting.
	*/
	#if defined (__PIC32MX__)
	SYSTEMConfigPerformance(GetSystemClock());
	#endif
	// Use PBCLK divider of 1:1 to calculate UART baud, timer tick etc.

	ResetDevice();

	SetBacklight(255);	//full brightness

	// Show a few colors as an opening screen

	_color = BLACK;
	ClearDevice();

	while(1)
	{

		_color = BRIGHTRED;
		ClearDevice();
		DelayMs(500);
		_color = BRIGHTGREEN;
		ClearDevice();
		DelayMs(500);
		_color = BRIGHTBLUE;
		ClearDevice();	
		DelayMs(500);

		for(counter = 0; counter <5000; counter++)
		{
			x1 = rand1(DISP_HOR_RESOLUTION);
			y1 = rand1(DISP_VER_RESOLUTION);
			x2 = rand1(DISP_HOR_RESOLUTION);
			y2 = rand1(DISP_VER_RESOLUTION);
			_color = RGB565CONVERT(rand1(255), rand1(255), rand1(255));
			DrawLine(x1,y1,x2,y2,_color);
		}

		_color = BLACK;
		ClearDevice();

		for(counter = 0; counter <2000; counter++)
		{
			x1 = rand1(DISP_HOR_RESOLUTION);
			y1 = rand1(DISP_VER_RESOLUTION);
			_color = RGB565CONVERT(rand1(255), rand1(255), rand1(255));
			PutPixel(x1,y1);
		}

		_color = BLACK;
		ClearDevice();
		


	}

}
//////////////////////////////////////// END OF MAIN /////////////////////////////////////////////////////
/*
**********************************************************************************************************
* A random generator from 
* http://www.daniweb.com/software-development/c/code/216329/construct-your-own-random-number-generator
**********************************************************************************************************
*/
unsigned int rand1(int lim)
{
	static long a = 100001;
	a = (a * 125) % 2796203;

    return ((a % lim) + 1);
}

/*
**********************************************************************************************************
* Line draw function from Programming The Nintendo Game Boy Advance: The Unofficial Guide
* Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
**********************************************************************************************************
*/
void DrawLine(int x1, int y1, int x2, int y2, int _color)
{
	int i, deltax, deltay, numpixels;
	int d, dinc1, dinc2;
	int x, xinc1, xinc2;
	int y, yinc1, yinc2;
	//calculate deltaX and deltaY
	deltax = fabs(x2 - x1);
	deltay = fabs(y2 - y1);

	//initialize
	if(deltax >= deltay)
	{
	//If x is independent variable
	numpixels = deltax + 1;
	d = (2 * deltay) - deltax;
	dinc1 = deltay << 1;
	dinc2 = (deltay - deltax) << 1;
	xinc1 = 1;
	xinc2 = 1;
	yinc1 = 0;
	yinc2 = 1;
	}
	else
	{
	//if y is independent variable
	numpixels = deltay + 1;
	d = (2 * deltax) - deltay;
	dinc1 = deltax << 1;
	dinc2 = (deltax - deltay) << 1;
	xinc1 = 0;
	xinc2 = 1;
	yinc1 = 1;
	yinc2 = 1;
	}

	//move the right direction
	if(x1 > x2)
	{
	xinc1 = -xinc1;
	xinc2 = -xinc2;
	}
	if(y1 > y2)
	{
	yinc1 = -yinc1;
	yinc2 = -yinc2;
	}

	x = x1;
	y = y1;
	//draw the pixels
	for(i = 1; i < numpixels; i++)
	{
	PutPixel(x, y);
	if(d < 0)
	{
		d = d + dinc1;
		x = x + xinc1;
		y = y + yinc1;
	}
	else
	{
		d = d + dinc2;
		x = x + xinc2;
		y = y + yinc2;
	}
	}
}
