/*
 *****************************************************************************
 * Module for Microchip Graphics Library
 * Solomon SSD1928 external LCD controller driver
 * 8/16-bit 8080 mode, 16bpp mode only
 * File modified from ssd1926.h for the hardware
 * 3.5" QVGA 16.7m color TFT LCD Module Evaluation Kit
 * Item number LVC75Z779 Eval Board (Version 1E)
 * 
 *
 * Author: John Leung
 * File: SSD1928.h
 * Company: TechToys Company
 * Web presence: www.TechToys.com.hk
 * Date: 7th March 2009
 *
 * The original software license agreement as stated below
 *****************************************************************************
*/

/*****************************************************************************
 *  Module for Microchip Graphics Library
 *  Solomon Systech. SSD1926 LCD controllers driver
 *  to be used with GFX 3 PICtail board
 *****************************************************************************
 * FileName:        SSD1926.h
 * Dependencies:    p24Fxxxx.h or plib.h
 * Processor:       PIC24, PIC32
 * Compiler:       	MPLAB C30, MPLAB C32
 * Linker:          MPLAB LINK30, MPLAB LINK32
 * Company:         Microchip Technology Incorporated
 *
 * Software License Agreement
 *
 * Copyright ?2008 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
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Anton Alkhimenok     08/27/08
 *****************************************************************************/

#ifndef _SSD1928_H
#define _SSD1928_H

#ifdef __PIC32MX
#include <plib.h>
#define PMDIN1   PMDIN
#else
#ifdef __PIC24F__
#include <p24Fxxxx.h>
#else
#error CONTROLLER IS NOT SUPPORTED
#endif
#endif

#include "GraphicsConfig.h"
#include "GenericTypeDefs.h"

// Definition for SPI interface for HIMAX 8238-A relevant to hardware layout
// SSD1928 specific 
#define GPIO3 3
#define GPIO2 2
#define GPIO1 1
#define GPIO0 0
#define LCD_RESET (1<<GPIO3)		//wiring for LCD Reset signal
#define LCD_SPENA (1<<GPIO2)		//wiring for LCD EN signal
#define LCD_SPCLK (1<<GPIO1)		//LCD SPI CLK
#define LCD_SPDAT (1<<GPIO0)		//LCD SPI DATA


#include "SSD1928_REG.h"

/*********************************************************************
* Overview: Allows using 16bit PMP interface (PIC32 only)
*********************************************************************/
//#define USE_16BIT_PMP

/*********************************************************************
* Overview: Additional hardware-accelerated functions can be implemented
*           in the driver. These definitions exclude the PutPixel()-based
*           functions in the primitives layer (Primitive.c file) from compilation.
*********************************************************************/

// Define this to implement Font related functions in the driver.
//#define USE_DRV_FONT

// Define this to implement Line function in the driver.
//#define USE_DRV_LINE

// Define this to implement Circle function in the driver.
//#define USE_DRV_CIRCLE

// Define this to implement FillCircle function in the driver.
//#define USE_DRV_FILLCIRCLE

// Define this to implement Bar function in the driver.
#define USE_DRV_BAR

// Define this to implement ClearDevice function in the driver.
#define USE_DRV_CLEARDEVICE

// Define this to implement PutImage function in the driver.
#define USE_DRV_PUTIMAGE

#ifndef DISP_HOR_RESOLUTION
#error  DISP_HOR_RESOLUTION must be defined in GraphicsConfig.h
#endif

#ifndef DISP_VER_RESOLUTION
#error  DISP_VER_RESOLUTION must be defined in GraphicsConfig.h
#endif

#ifndef COLOR_DEPTH
#error  COLOR_DEPTH must be defined in GraphicsConfig.h
#endif

#ifndef DISP_ORIENTATION
#error  DISP_ORIENTATION must be defined in GraphicsConfig.h
#endif

/*********************************************************************
* Overview: Horizontal synchronization timing in pixels
*                  (from the glass datasheet).
*********************************************************************/

#ifndef DISP_HOR_PULSE_WIDTH
#error  DISP_HOR_PULSE_WIDTH must be defined in GraphicsConfig.h
#endif
#ifndef DISP_HOR_BACK_PORCH
#error  DISP_HOR_BACK_PORCH must be defined in GraphicsConfig.h
#endif
#ifndef DISP_HOR_FRONT_PORCH
#error  DISP_HOR_FRONT_PORCH must be defined in GraphicsConfig.h
#endif


/*********************************************************************
* Overview: Vertical synchronization timing in lines
*                  (from the glass datasheet).
*********************************************************************/

#ifndef DISP_VER_PULSE_WIDTH
#error  DISP_VER_PULSE_WIDTH must be defined in GraphicsConfig.h
#endif
#ifndef DISP_VER_BACK_PORCH
#error  DISP_VER_BACK_PORCH must be defined in GraphicsConfig.h
#endif
#ifndef DISP_VER_FRONT_PORCH
#error  DISP_VER_FRONT_PORCH must be defined in GraphicsConfig.h
#endif


/*********************************************************************
* PARAMETERS VALIDATION
*********************************************************************/
#if COLOR_DEPTH != 16
#error This driver supports 16 BPP only.
#endif

#if (DISP_HOR_RESOLUTION % 8) != 0
#error Horizontal resolution must be divisible by 8.
#endif

#if (DISP_ORIENTATION != 0) && (DISP_ORIENTATION != 180) && (DISP_ORIENTATION != 90) && (DISP_ORIENTATION != 270)
#error The display orientation selected is not supported. It can be only 0,90,180 or 270.
#endif

/*********************************************************************
* Overview: Clipping region control codes to be used with SetClip(...)
*           function. 
*********************************************************************/
#define CLIP_DISABLE       0 	// Disables clipping.
#define CLIP_ENABLE        1	// Enables clipping.

/*********************************************************************
* Overview: Some basic colors definitions.
*********************************************************************/
#define BLACK               RGB565CONVERT(0,    0,      0)
#define BRIGHTBLUE          RGB565CONVERT(0,    0,      255)
#define BRIGHTGREEN         RGB565CONVERT(0,    255,    0)
#define BRIGHTCYAN          RGB565CONVERT(0,    255,    255)
#define BRIGHTRED           RGB565CONVERT(255,  0,      0)
#define BRIGHTMAGENTA       RGB565CONVERT(255,  0,      255)
#define BRIGHTYELLOW        RGB565CONVERT(255,  255,    0)
#define BLUE                RGB565CONVERT(0,    0,      128)
#define GREEN               RGB565CONVERT(0,    128,    0)
#define CYAN                RGB565CONVERT(0,    128,    128)
#define RED                 RGB565CONVERT(128,  0,      0)
#define MAGENTA             RGB565CONVERT(128,  0,      128)
#define BROWN               RGB565CONVERT(255,  128,    0)
#define LIGHTGRAY           RGB565CONVERT(128,  128,    128)
#define DARKGRAY            RGB565CONVERT(64,   64,     64)
#define LIGHTBLUE           RGB565CONVERT(128,  128,    255)
#define LIGHTGREEN          RGB565CONVERT(128,  255,    128)
#define LIGHTCYAN           RGB565CONVERT(128,  255,    255)
#define LIGHTRED            RGB565CONVERT(255,  128,    128)
#define LIGHTMAGENTA        RGB565CONVERT(255,  128,    255)
#define YELLOW              RGB565CONVERT(255,  255,    128)
#define WHITE               RGB565CONVERT(255,  255,    255)
                            
#define GRAY0       	    RGB565CONVERT(224,  224,    224)
#define GRAY1         	    RGB565CONVERT(192,  192,    192)   
#define GRAY2               RGB565CONVERT(160,  160,    160)   
#define GRAY3               RGB565CONVERT(128,  128,    128)
#define GRAY4               RGB565CONVERT(96,   96,     96)
#define GRAY5               RGB565CONVERT(64,   64,     64)
#define GRAY6	            RGB565CONVERT(32,   32,     32)


/*********************************************************************
* Overview: Extern for the current color
*********************************************************************/
extern WORD _color;

/*********************************************************************
* Overview: Clipping region control and border settings.
*********************************************************************/
// Clipping region enable control
extern SHORT _clipRgn;

// Left clipping region border
extern SHORT _clipLeft;
// Top clipping region border
extern SHORT _clipTop;
// Right clipping region border
extern SHORT _clipRight;
// Bottom clipping region border
extern SHORT _clipBottom;


// Active and Visual Pages 
extern BYTE _activePage;
extern BYTE	_visualPage;

// line memory pitch for main window & floating windows. 
// For main window, it is the default value LINE_MEM_PITCH
extern DWORD _line_mem_pitch;
// SSD1928 specific
extern BYTE  _gpioStatus;

/*
*************************************************************************************
* Function: 	Send a value in 16-bit word to a register 'index'
*
* PreCondition: dependency on SetRegB(WORD index, BYTE value)
*				
*
* Arguments: 	'WORD' index - register number in WORD format
*				'WORD' value - in 16-bit format
* Return: 		none
*
* Note:			Address of index register denotes the lower starting address
*************************************************************************************
*/
void SetRegW(WORD index, WORD value);

/*
*************************************************************************************
* Function: 	Send a 32-bit DWORD value to a register 'index'
*
* PreCondition: dependency on SetRegW(WORD index, WORD value)
*
* Arguments:	'WORD' index - register number in WORD format
*				'DWORD' value in 32-bit format
* Return: none
*
* Note:			Address of index register denotes the lower starting address.
*				Registers of SSD1928 have been arranged such that 
*				no register will be set for the 4th most significant byte
*				when the width of the register is 24-bit wide.
*				For example, REG_DV_DV0_START_ADDR_X occupy 0x1b0:2
*				REG_DV_DV0_START_ADDR_0		   	0x1b0
*				REG_DV_DV0_START_ADDR_1		   	0x1b1
*				REG_DV_DV0_START_ADDR_2   		0x1b2
*				
*				There is nothing at memory 0x1b3 and it skips to 0x1b4 for 
*				REG_DV_DV1_START_ADDR_0.
*				This makes SetRegL(WORD index, DWORD value)
*				work perfectly for a complete 16-bit access in upper and lower words
*				format. Otherwise, this function will set something for the register at
*				the highest byte location with a wrong value
*************************************************************************************
*/
void SetRegL(WORD index, DWORD value);

/*
*************************************************************************************
* Function: 	Get a 32-bit DWORD value from a register at 'index'
*
* PreCondition: dependency on GetRegW(WORD index)
*
* Arguments:	'WORD' index - register number in WORD format
* Return: 		The DWORD value from register at 'index'
*
* Note:			
*************************************************************************************
*/
DWORD GetRegL(WORD index);					//get back a DWORD value (32 bit unsigned) from the register at location index

/*
*************************************************************************************
* Function: 	Float window initialization function
*
* Arguments:	DWORD startaddr - 	it is the starting address on the image buffer.
*									There is 256KB buffer in SSD1928
*				WORD  linewidth - 	line address offset. This variable sets the display
*									width of the Floating Window.
*				WORD x			-	It is the location for x-coordinate of the Floating Window
*				WORD y			-	It is the location for y-coordinate of the Floating Window
*									is supported in this version. No effect in this version
*				WORD width		- 	Width of the Floating Window
*				WORD height		-	Height of the Floating Window
*				BOOL rgb		-	0 for YUV mode
*									1 for RGB mode
*
* Return:		None	
*
* Note: 		For 16bpp only. Float window initialization is a critical routine for
*				definition on linewidth which is very important for memory map.
*************************************************************************************
*/
void ssd1928_FloatWndInit(DWORD startaddr, WORD linewidth, WORD x, WORD y,  WORD width, WORD height, BOOL rgb);

/*
*************************************************************************************
* Function: 	Enable/disable Floating window
*
* PreCondition:	We need to enable the Main Window prior to enable the Float Window
*
* Arguments: 	BOOL enable	- 	TRUE to enable the Float Window
*								FALSE to disable the Float Window, Float window will be blank
*
* Return:		
* Note: 		For 16bpp only
*************************************************************************************
*/
void ssd1928_FloatWndEnable(BOOL enable);

/*
*************************************************************************************
* Function: 	Main window initialization function
*
* PreCondition:	InitGraph(), inside we need ResetDevice()
*
* Arguments:	DWORD startaddr - 	it is the starting address on the image buffer.
*									There is 256KB buffer in SSD1928
*				WORD  linewidth - 	line address offset. This variable sets the display
*									width. It is possible to set this parameter larger
*									or smaller than the physical display width 
*									(i.e. 320 for Landscape, 240 for portrait) for special
*									effect like display pan or jpeg file display with 
*									smaller image width
*				WORD bpp		-	It is the bit per pixel, for this version, only 16-bit
*									color is supported, therefore it has been fixed to 16
*				BYTE orient		-	Orientation of the display. Only zero degree rotation
*									is supported in this version. No effect in this version
*				BOOL rgb		-	color mode of the display, either '1' for RGB, '0' for YUV
*									YUV mode is used for jpeg decode display.
*									RGB mode is used for video, and normal display
*
* Return:		None
*
* Note:			Main Window Display Start Address Register0, 1, & 2 occupy
*				REG[74h], REG[75h], & REG[76h]. These bits from the 17-bit address
*				for starting double-word of the LCD image in the display buffer
*				for the Main Window. 
*************************************************************************************
*/
void ssd1928_MainWndInit(DWORD startaddr, WORD linewidth, WORD bpp, BYTE orient, BOOL rgb);

/*
*************************************************************************************
* Function:		Set focus on Main Window or Floating Window
*
* PreCondition:	None
*
* Arguments: 	BYTE wnd		0 for Main Window
*								1 for Floating Window
* Return:		None
*	
* Note:
*************************************************************************************
*/
void ssd1928_FocusWnd(BYTE wnd);

/*
*************************************************************************************
* Function:		Enable/disable the Main Window
*
* PreCondition:	None
*
* Arguments: 	BOOL enable	- 	TRUE to enable the Main Window
*								FALSE to disable the Main Window, display will be blank
* Return:		None
*	
* Note:
*************************************************************************************
*/
void ssd1928_MainWndEnable(BOOL enable);


/*********************************************************************
* Function:  void ResetDevice()
*
* Overview: Initializes LCD module.
*
* PreCondition: none
*
* Input: none
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
void ResetDevice(void);

/*********************************************************************
* Macros:  GetMaxX()
*
* Overview: Returns maximum horizontal coordinate.
*
* PreCondition: none
*
* Input: none
*
* Output: Maximum horizontal coordinate.
*
* Side Effects: none
*
* Note: Change for Virtual display
*		Original Microchip driver uses DISP_VER_RESOLUTION instead
********************************************************************/
#if (DISP_ORIENTATION == 90) || (DISP_ORIENTATION == 270)

#define	GetMaxX() (DISP_VIRTUAL_VER_RESOLUTION-1)

#elif (DISP_ORIENTATION == 0) || (DISP_ORIENTATION == 180)

#define	GetMaxX() (DISP_VIRTUAL_HOR_RESOLUTION-1)

#endif

/*********************************************************************
* Macros:  GetMaxY()
*
* Overview: Returns maximum vertical coordinate.
*
* PreCondition: none
*
* Input: none
*
* Output: Maximum vertical coordinate.
*
* Side Effects: none
*
* Note: Change for Virtual display
*		Original Microchip driver uses DISP_HOR_RESOLUTION instead
********************************************************************/
#if (DISP_ORIENTATION == 90) || (DISP_ORIENTATION == 270)

#define	GetMaxY() (DISP_VIRTUAL_HOR_RESOLUTION-1)

#elif (DISP_ORIENTATION == 0) || (DISP_ORIENTATION == 180)

#define	GetMaxY() (DISP_VIRTUAL_VER_RESOLUTION-1)

#endif

// Definition for memory page size with virtual display taken into account
// The maximum memory space of SSD1928 is 262kbyte
#ifndef PAGE_MEM_SIZE
// Memory allocation for a single page 
#define PAGE_MEM_SIZE 	(GetMaxX()+1)*(GetMaxY()+1)*COLOR_DEPTH/8

#if PAGE_MEM_SIZE > 262000ul
#error MEMORY ALLOCATION FAILED. CHECK SSD1928.h
#endif

#endif


/*********************************************************************
* Macros:  SetColor(color)
*
* Overview: Sets current drawing color.
*
* PreCondition: none
*
* Input: color - Color coded in 5:6:5 RGB format.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
#define SetColor(color) _color = color

/*********************************************************************
* Macros:  GetColor()
*
* Overview: Returns current drawing color.
*
* PreCondition: none
*
* Input: none
*
* Output: Color coded in 5:6:5 RGB format.
*
* Side Effects: none
*
********************************************************************/
#define GetColor() _color

/*********************************************************************
* Macros:  SetActivePage(page)
*
* Overview: Sets active graphic page.
*
* PreCondition: none
*
* Input: page - Graphic page number.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
#define SetActivePage(page)	_activePage = page

/*********************************************************************
* Macros: SetVisualPage(page)
*
* Overview: Sets graphic page to display.
*
* PreCondition: none
*
* Input: page - Graphic page number
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
#define SetVisualPage(page)	_visualPage = page

/*********************************************************************
* Function: void PutPixel(SHORT x, SHORT y)
*
* Overview: Puts pixel with the given x,y coordinate position.
*
* PreCondition: none
*
* Input: x - x position of the pixel.
*		 y - y position of the pixel.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
void PutPixel(SHORT x, SHORT y);

/*********************************************************************
* Function: WORD GetPixel(SHORT x, SHORT y)
*
* Overview: Returns pixel color at the given x,y coordinate position.
*
* PreCondition: none
*
* Input: x - x position of the pixel.
*		 y - y position of the pixel.
*
* Output: pixel color
*
* Side Effects: none
*
********************************************************************/
WORD GetPixel(SHORT x, SHORT y);

/*********************************************************************
* Macros: SetClipRgn(left, top, right, bottom)
*
* Overview: Sets clipping region.
*
* PreCondition: none
*
* Input: left - Defines the left clipping region border.
*		 top - Defines the top clipping region border.
*		 right - Defines the right clipping region border.
*	     bottom - Defines the bottom clipping region border.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
#define SetClipRgn(left,top,right,bottom) _clipLeft=left; _clipTop=top; _clipRight=right; _clipBottom=bottom;

/*********************************************************************
* Macros: GetClipLeft()
*
* Overview: Returns left clipping border.
*
* PreCondition: none
*
* Input: none
*
* Output: Left clipping border.
*
* Side Effects: none
*
********************************************************************/
#define GetClipLeft() _clipLeft

/*********************************************************************
* Macros: GetClipRight()
*
* Overview: Returns right clipping border.
*
* PreCondition: none
*
* Input: none
*
* Output: Right clipping border.
*
* Side Effects: none
*
********************************************************************/
#define GetClipRight() _clipRight

/*********************************************************************
* Macros: GetClipTop()
*
* Overview: Returns top clipping border.
*
* PreCondition: none
*
* Input: none
*
* Output: Top clipping border.
*
* Side Effects: none
*
********************************************************************/
#define GetClipTop() _clipTop

/*********************************************************************
* Macros: GetClipBottom()
*
* Overview: Returns bottom clipping border.
*
* PreCondition: none
*
* Input: none
*
* Output: Bottom clipping border.
*
* Side Effects: none
*
********************************************************************/
#define GetClipBottom() _clipBottom

/*********************************************************************
* Macros: SetClip(control)
*
* Overview: Enables/disables clipping.
*
* PreCondition: none
*
* Input: control - Enables or disables the clipping.
*			- 0: Disable clipping
*			- 1: Enable clipping
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
#define SetClip(control) _clipRgn=control;

/*********************************************************************
* Macros: IsDeviceBusy()
*
* Overview: Returns non-zero if LCD controller is busy 
*           (previous drawing operation is not completed).
*
* PreCondition: none
*
* Input: none
*
* Output: Busy status.
*
* Side Effects: none
*
********************************************************************/
#define IsDeviceBusy()  0

/*********************************************************************
* Macros: SetPalette(colorNum, color)
*
* Overview:  Sets palette register.
*
* PreCondition: none
*
* Input: colorNum - Register number.
*        color - Color.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
#define SetPalette(colorNum, color)

/*********************************************************************
* Function:  void  DelayMs(WORD time)
*
* Overview: Delays execution on time specified in milliseconds.
*           The delay is correct only for 16MIPS.
*
* PreCondition: none
*
* Input: time - Delay in milliseconds.
*
* Output: none
*
* Side Effects: none
*
********************************************************************/
void DelayMs(WORD time);

/*********************************************************************
* Function:  Set Display Start Position 
*
* Overview: 
*
* PreCondition: #define USE_VIRTUAL_DISPLAY under GraphicsConfig.h
*
* Input: 	x,y - pixel coordinates
*			clipLeftRgn, clipTopBottom - if it clips at left, right
*			top, and bottom. If clipLeftRgn set FALSE, display
*			will "wrap" around on boundary. The same for clipTopBottom
* Output: none
*
* Side Effects: 
*
********************************************************************/
#ifdef USE_VIRTUAL_DISPLAY
void SetPageOrigin(BOOL clipLeftRgn, BOOL clipTopBottom, SHORT x, SHORT y);
#endif


#endif // _SSD1928_H
