/*
 *****************************************************************************
 * Module for Microchip Graphics Library
 * Solomon SSD1928 external LCD controller driver
 * 8/16-bit 8080 mode, 16bpp mode only
 *
 * Author: John Leung
 * File: SSD1928.h
 * Company: TechToys Company
 * Web presence: www.TechToys.com.hk
 * Date: 11 June 2008
 *
 * Note:			Original source code from Microchip Graphic Library 
 *					The original software license agreement as stated below:
 *
 * 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.
 *****************************************************************************
*/

/*
******************************************************************************
* 1st Aug 08
* Add _gpioStatus for ssd1928¡¦s SPI
******************************************************************************
*/

/*
******************************************************************************
* 11st Aug 2008
* Introduction of 
* 1) BYTE _page for SetActivePage(page) & SetVisualPage(page)
* 2) DWORD _line_mem_pitch for LINE_MEM_PITCH, change all LINE_MEM_PITCH
*		constants to variable _line_mem_picth
* 3) Change PutPixel(x,y) for _line_mem_pitch
* 4) SetLinePitch(pitch) for InitGraph() under primitive.c
* 5) Change Bar() for _line_mem_pitch
* 6) PAGE_MEM_SIZE for SCREEN_HOR_SIZE*SCREEN_VER_SIZE*2 under ssd1928.h
******************************************************************************
*/

/*
******************************************************************************
* 24th Sept 2008
* 1) Modify GetReg(index) for 8-bit operation by using 0xFF instead of 0xFFFF
*	 for data port operation
******************************************************************************
*/

/*
******************************************************************************
* 28th Sept 2008
* 1) Add GetRegW(WORD index), but you need to test it before use.
******************************************************************************
*/

/*
******************************************************************************
* 30th Sept 2008
* 1) Tested GetRegW(WORD index) with the register at REG_FLOAT_WIN_X_END_POS0
*		which seems OK.
*
******************************************************************************
*/

/*
******************************************************************************
* 28th Nov 2008
* 1) Move low level I/O function prototype incl. 
*		SetRegW(WORD index, WORD value);
*		SetRegL(WORD index, DWORD value);
*		GetRegL(WORD index);
*		to SSD1928.h to solve the pecular error for ssd1928_sdhc.c
******************************************************************************
*/

/*
******************************************************************************
* 23 Jan 2009
* SSD1928.h header file modified for the hardware platform PIC24-Eval RevC
******************************************************************************
*/
#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"


#define USE_LANDSCAPE
//#define PORTRAIT		//use either Lanscape or Portrait mode
#define USE_8BIT_8080	//use either 8-bit or 16-bit for accessing mode
//#define USE_16BIT_8080

// 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"

// Additional hardware-accelerated functions implemented in the driver.
// These definitions exclude from compilation the PutPixel()-based functions
// in the graphic primitive layer (Primitive.c file).

//#define USE_DRV_FONT
//#define USE_DRV_LINE
//#define USE_DRV_CIRCLE
//#define USE_DRV_FILLCIRCLE
#define USE_DRV_BAR
#define USE_DRV_CLEARDEVICE
#define USE_DRV_PUTIMAGE


/*********************************************************************
* Overview: Horizontal or vertical screen size.
*********************************************************************/

#ifdef USE_LANDSCAPE
// Defines the horizontal screen size. Dependent on the display glass used.
#define SCREEN_HOR_SIZE    320
// Defines the vertical screen size. Dependent on the display glass used.
#define SCREEN_VER_SIZE    240
// Memory pitch for line, and this value is value for 8-bit access because 1-line eq. 
// 320 pixels and 1 pixel accounts for 2 bytes in 16bbp mode, this this value is 
// twice 320, i.e. 640
#define LINE_MEM_PITCH     320 

#else

// Defines the horizontal screen size. Dependent on the display glass used.
#define SCREEN_HOR_SIZE    240
// Defines the vertical screen size. Dependent on the display glass used.
#define SCREEN_VER_SIZE	   320
// Memory pitch for line, and this value is value for 8-bit access because 1-line eq. 
// 240 pixels and 1 pixel accounts for 2 bytes in 16bbp mode, this this value is 
// twice 240, i.e. 480
#define LINE_MEM_PITCH     240 

#endif

#define PAGE_MEM_SIZE	   153600L	//SCREEN_HOR_SIZE*SCREEN_VER_SIZE*2 
/*
*****************************************************************************
* Use 8080 system interface. No PMP module used. Discrete IO method employed
* Function		mcu pins		LCD pins
* ==========	========		========
* SLEEP			RG15			SLEEP
* DATA LINES	PMD[7:0]		DAT[7:0] in 8-bit mode
* RESET			RA7				/RESET
* CHIP SELECT	RD11			/CS
* COMMAND/DATA	RA6				RS 
* WR STROBE		RD4/PMPWR		/WR
* RD STROBE		RD5/PMPRD		/RD
* LED backlight RF8				EN
*
*****************************************************************************
*/

//Definitions for SLEEP pin of SSD1928
#define SLEEP_TRIS_BIT	   TRISGbits.TRISG15
#define SLEEP_LAT_BIT	   LATGbits.LATG15

// Definitions for reset pin
#define RST_TRIS_BIT       TRISAbits.TRISA7
#define RST_LAT_BIT        LATAbits.LATA7

// Definitions for CS pin
#define CS_TRIS_BIT        TRISDbits.TRISD11
#define CS_LAT_BIT         LATDbits.LATD11

//Definition for RS pin
#define RS_TRIS_BIT			TRISAbits.TRISA6
#define RS_LAT_BIT			LATAbits.LATA6

//Definition for RD pin
#define RD_TRIS_BIT			TRISDbits.TRISD5
#define RD_LAT_BIT			LATDbits.LATD5

//Definition for WR pin
#define WR_TRIS_BIT			TRISDbits.TRISD4
#define WR_LAT_BIT			LATDbits.LATD4

//Definition for data BUS
#define DAT_TRIS_BIT		TRISE
#define DAT_LAT_BIT			LATE
#define DAT_PORT_BIT		PORTE

//Defintion for backlight control
#define LED_TRIS_BIT		TRISFbits.TRISF8
#define LED_LAT_BIT			LATFbits.LATF8

// Clipping region control codes
#define CLIP_DISABLE       0 
#define CLIP_ENABLE        1


/*********************************************************************
* Overview: Some basic colors definitions.
*********************************************************************/
// Color codes
                            
#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)

// Color
extern WORD _color;

// Page
extern BYTE	_page;

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

// Clipping region control
extern SHORT _clipRgn;

// Clipping region borders
extern SHORT _clipLeft;
extern SHORT _clipTop;
extern SHORT _clipRight;
extern SHORT _clipBottom;

// 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


/*********************************************************************
* Macros:  PMPDelay()
*
* PreCondition: none
*
* Input: none
*
* Output: none
*
* Side Effects: none
*
* Overview: delays execution for PMP cycle time
*
* Note: none
*
********************************************************************/
#define PMPDelay()  Nop(); Nop(); Nop(); Nop();

/*********************************************************************
* Function:  void ResetDevice()
*
* PreCondition: none
*
* Input: none
*
* Output: none
*
* Side Effects: none
*
* Overview: Initialize low level IO port for mcu,
*			configure LCD via SPI, initialize SSD1928 for PCLK, HYSNC, VSYNC etc
*
* Note: none
*
********************************************************************/
void ResetDevice(void);

/*********************************************************************
* Macros:  GetMaxX()
*
* PreCondition: none
*
* Input: none
*
* Output: maximum horizontal coordinate
*
* Side Effects: none
*
* Overview: returns maximum horizontal coordinate
*
* Note: none
*
********************************************************************/
#define GetMaxX() (SCREEN_HOR_SIZE-1)

/*********************************************************************
* Macros:  GetMaxY()
*
* PreCondition: none
*
* Input: none
*
* Output: maximum vertical coordinate
*
* Side Effects: none
*
* Overview: returns maximum vertical coordinate
*
* Note: none
*
********************************************************************/
#define GetMaxY() (SCREEN_VER_SIZE-1)

/*********************************************************************
* Macros:  SetColor(color)
*
* PreCondition: none
*
* Input: color coded in format:
*           bits 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 
*          color  R  R  R  R  R  G  G  G  G  G  G  B  B  B  B  B
*
* Output: none
*
* Side Effects: none
*
* Overview: sets current color
*
* Note: none
*
********************************************************************/
#define SetColor(color) _color = color;

/*********************************************************************
* Macros:  GetColor()
*
* PreCondition: none
*
* Input: none
*
* Output:  color coded in format:
*           bits 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 
*          color  R  R  R  R  R  G  G  G  G  G  G  B  B  B  B  B
*
* Side Effects: none
*
* Overview: returns current color
*
* Note: none
*
********************************************************************/
#define GetColor() _color

/*********************************************************************
* Macros:  SetActivePage(page)
*
* PreCondition: none
*
* Input: graphic page number
*
* Output: none
*
* Side Effects: none
*
* Overview: sets active graphic page 
*
* Note: the controller has only page
*
********************************************************************/
#define SetActivePage(page)

/*********************************************************************
* Macros: SetVisualPage(page)
*
* PreCondition: none
*
* Input: graphic page number
*
* Output: none
*
* Side Effects: none
*
* Overview: sets graphic page to display
*
* Note: the controller has only page
*
********************************************************************/
#define SetVisualPage(page)


/*********************************************************************
* Function: void PutPixel(SHORT x, SHORT y)
*
* PreCondition: none
*
* Input: x,y - pixel coordinates 
*
* Output: none
*
* Side Effects: none
*
* Overview: puts pixel
*
* Note: none
*
********************************************************************/
void PutPixel(SHORT x, SHORT y);

/*********************************************************************
* Function: WORD GetPixel(SHORT x, SHORT y)
*
* PreCondition: none
*
* Input: x,y - pixel coordinates 
*
* Output: pixel color
*
* Side Effects: none
*
* Overview: returns pixel color at x,y position
*
* Note: none
*
********************************************************************/
WORD GetPixel(SHORT x, SHORT y);

/*********************************************************************
* Macros: SetClipRgn(left, top, right, bottom)
*
* PreCondition: none
*
* Input: left,top,right,bottom - clipping region borders
*
* Output: none
*
* Side Effects: none
*
* Overview: sets clipping region 
*
* Note: none
*
********************************************************************/
#define SetClipRgn(left,top,right,bottom) _clipLeft=left; _clipTop=top; _clipRight=right; _clipBottom=bottom;

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

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

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

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

/*********************************************************************
* Macros: SetClip(control)
*
* PreCondition: none
*
* Input: control - 0 disable/ 1 enable
*
* Output: none
*
* Side Effects: none
*
* Overview: enables/disables clipping 
*
* Note: none
*
********************************************************************/
#define SetClip(control) _clipRgn=control;

/*********************************************************************
* Macros: IsDeviceBusy()
*
* PreCondition: none
*
* Input: none
*
* Output: busy status
*
* Side Effects: none
*
* Overview:  returns non-zero if LCD controller is busy 
* (previous drawing operation is not complete)
*
* Note: the controller is always accessible
*
********************************************************************/
#define IsDeviceBusy()  0

/*********************************************************************
* Macros: SetPalette(colorNum, color)
*
* PreCondition: none
*
* Input: colorNum - register number, color - color
*
* Output: none
*
* Side Effects: none
*
* Overview:  sets palette register
*
* Note: the controller has no palette
*
********************************************************************/
#define SetPalette(colorNum, color)

/*********************************************************************
* Function:  void  DelayMs(WORD time)
*
* PreCondition: none
*
* Input: time - delay in ms
*
* Output: none
*
* Side Effects: none
*
* Overview: delays execution on time specified in ms
*
* Note: delay is defined for 16MIPS
*
********************************************************************/
void DelayMs(WORD time);


//void ssd1928_SetPage(DWORD startaddr);

/*
*************************************************************************************
* 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);

#endif // _SSD1928_H
