#ifndef PART_TM4C123GH6PM
#define PART_TM4C123GH6PM
#endif


#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "LCDDriver.h"
#include "LCD_Matrix.h"
#include "driverlib/ssi.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"


/*     _________
 * 				|
 * 			 PC6|-->SCK		ʱ
 *			 PC7|-->SDA		ݴ
 *	TIVA  	 PB1|-->CS		͵ƽƬѡ
 *			 PD1|-->CD		/ָĴ
 *			 PE5|-->RST		͵ƽλ
 *	   _________|
*/
// ͵ƽƬѡ
#define setCS  GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, GPIO_PIN_1);	//PB1
#define rstCS  GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, 0);

// Ĵѡź
#define setCD  GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_6, GPIO_PIN_6);	//PC6
#define rstCD  GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_6, 0);

// ͵ƽλλɺ󣬻صߵƽҺģ鿪ʼ
#define setRES GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5, GPIO_PIN_5);	//PE5
#define rstRES GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5, 0);

/******************************************************************************
 * @brief  еʾ
 * @param
 * @return none
 ******************************************************************************/
void LCD_ScreenClr() {
	unsigned char i, j;
	for (i = 0; i < 9; i++)				//ѭ0~8ҳ
	{
		rstCS
		LCD_TransferCmd(0xb0 + i);		//ѡҳ
		LCD_TransferCmd(0x10);			//ѡС
		LCD_TransferCmd(0x00);
		for (j = 0; j < 132; j++) {
			LCD_TransferData(0x00);		//0x00ʾ0x00
		}
	}
}

/******************************************************************************
 * @brief  Һ˿ڳʼ
 * @param
 * @return none
 ******************************************************************************/
void LCD_Enable()
{
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);					//˿ʹ
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
//	-----------------------------------------------------------------------------
	GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_1);				//˿ΪPB1->CS
	GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_6);				//PC6->CD
	GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_5);				//PE5->RST

//	-----------------------------------------------------------------------------

    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);						//ϵͳʹ
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    GPIOPinConfigure(GPIO_PD0_SSI3CLK);								//PD0PD3
    GPIOPinConfigure(GPIO_PD3_SSI3TX);

    GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_3);		//SSI˿ڹʹ

    SSIConfigSetExpClk(SSI3_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 50000, 8);	//SSI3,˿ģʽ:50K,8λݣSSI_FRF_MOTO_MODE_0ģʽ

    SSIEnable(SSI3_BASE);
//  -----------------------------------------------------------------------------
}

/******************************************************************************
 * @brief  ϳʱʱ
 * @param
 * @return none
 ******************************************************************************/
void LCD_Delay2(unsigned int i) {
	int j, k;
	for (j = 0; j < i; j++)
		for (k = 0; k < 990; k++)
			;
}

/******************************************************************************
 * @brief  ϶ʱʱ
 * @param
 * @return none
 ******************************************************************************/
void LCD_Delay3(unsigned int i) {
	int j, k;
	for (j = 0; j < i; j++)
		for (k = 0; k < 10; k++)
			;
}



/******************************************************************************
 * @brief  	ʾ8*8ľ
 * @param	data ʾָ
 * @param	type ǷҪʾ
 * @return  none
 ******************************************************************************/
void LCD_TransferData(unsigned char data) {

	rstCS
	setCD

    while(SSIBusy(SSI3_BASE));
    SSIDataPut(SSI3_BASE, data);
    while(SSIBusy(SSI3_BASE));
}

/******************************************************************************
 * @brief  	Һ
 * @param	command ַ
 * @return  none
 ******************************************************************************/
void LCD_TransferCmd(unsigned char command) {

	rstCS
	rstCD

    while(SSIBusy(SSI3_BASE));
    SSIDataPut(SSI3_BASE, command);
    while(SSIBusy(SSI3_BASE));
}

/******************************************************************************
 * @brief  	ʼҺ
 * @param	none
 * @return  none
 ******************************************************************************/
void LCD_Init() {
	rstRES
	LCD_Delay2(50);                 //delay
	setRES
	LCD_Delay2(50);                 //delay
	LCD_TransferCmd(0xe2); 			/*λ*/
	LCD_TransferCmd(0x2c); 			/*ѹ1*/
	LCD_TransferCmd(0x2e); 			/*ѹ2*/
	LCD_TransferCmd(0x2f); 			/*ѹ3*/
	LCD_TransferCmd(0x23); 			/*ֵԱȶȣ÷Χ2027*/
	LCD_TransferCmd(0x81);			/*΢Աȶ*/
	LCD_TransferCmd(0x28); 			/*΢Աȶȵֵ÷Χ063*/
	LCD_TransferCmd(0xa2); 			/*1/9 ƫѹȣbias*/
	LCD_TransferCmd(0xc8); 			/*ɨ˳򣺴ϵc0 c8 */
	LCD_TransferCmd(0xa0); 			/*ɨ˳򣺴 a0 a1*/
	LCD_TransferCmd(0xa6); 			/* 0xa6 0xa7*/
	LCD_TransferCmd(0xaf); 			/*ʾ*/

}


/******************************************************************************
 * @brief  	Һ8*8ģ˳ʱ90ȵתҺʾģʽ
 * @param	c	Ҫʾַֻ
 * @param	row	ַʾ ȡֵΧ0~3
 * @param	col	ַʾ ȡֵΧ0~119
 * @return  0  ʾ
 *			1 ʾʾɹ
 ******************************************************************************/
unsigned char LCD_Draw_Char(char c, unsigned char row, unsigned char col) {

	unsigned char * add = asc + (c - 0x20) * 16;
	unsigned int i,j;							//
	unsigned char col_0 = col;					// λ
	unsigned char col_1 = col >> 4;  			// λ

	//-----------------------------
	//--------------0ʾ---------------
	if (col > LCD_MAX_COL - 1) {
		return 0;
	}
	if (row > LCD_MAX_RAW - 1) {
		return 0;
	}

	for (i = 0; i < 2; i++)
	{
		rstCS
		LCD_TransferCmd(0xb0 + row * 2 + i);            //áҳ
		LCD_TransferCmd(0x10 + (col_1 & 0x0f));			//áСԼеĸλ
		LCD_TransferCmd(0x00 + (col_0 & 0x0f));			//áСԼеĵλ
		for (j = 0; j < 8; j++)
		{
			LCD_TransferData(*add);
			add++;
		}
	}

	return 1; 								//1ʾִгɹ
}


/******************************************************************************
 * @brief  	Һ8*8ģ˳ʱ90ȵתҺʾģʽ
 * @param	index	Ҫʾĺֵģ
 * @param	row	ַʾ ,ȡֵΧ0~3
 * @param	col	ַʾ ,ȡֵΧ0~119
 * @return  0  ʾ
 *			1 ʾʾɹ
 ******************************************************************************/
unsigned char LCD_Draw_Chinese(unsigned char index, unsigned char row,
		unsigned char col) {
	unsigned char * chinese = CHINESE_MATRIX + 32 * index;
	unsigned int i, j;					//
	unsigned char col_0 = col;		//еλ
	unsigned char col_1 = col >> 4;  //иλ

	//-----------------------------
	//-----------0ʾ------------
	if (col > 111) {
		return 0;
	}
	if (row > 3) {
		return 0;
	}

	for (i = 0; i < 2; i++)
	{
		rstCS
		LCD_TransferCmd(0xb0 + row * 2 + i);             //áҳ
		LCD_TransferCmd(0x10 + (col_1 & 0x0f));			 //áСԼеĸλ
		LCD_TransferCmd(0x00 + (col_0 & 0x0f));			 //áСԼеĵλ
		for (j = 0; j < 16; j++)
		{
			LCD_TransferData(*chinese);
			chinese++;
		}
	}
	return 1; //1ʾִгɹ
}

/************************************************************
 * @brief  	Զ˿CDаʼ
 * @param	none
 * @param	none
 ***********************************************************/
void Init_Key()
{
	//ʼGPIO
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

	// PDΪ2MA
	GPIOPadConfigSet(GPIO_PORTD_BASE,  GPIO_PIN_6, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
	GPIOPadConfigSet(GPIO_PORTC_BASE,  GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
//	GPIOPadConfigSet(GPIO_PORTD_BASE,  GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

	//GPIOģʽ
	GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_6, GPIO_DIR_MODE_IN);
	GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_DIR_MODE_IN);
//	GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_7, GPIO_DIR_MODE_IN);

	}


/************************************************************************
 * ʼADCȡֵѹֵ
 * 		
 * 				|
//			 PC6|<--Button1
 * 	TIVA	 PD6|<--Button2
 * 			 PD7|<--Button3
//		________|
 *
 *  @return	0x00
 *  		0x01
 *  		0x02
 ***********************************************************************/
unsigned char scan_key(void)
{

	if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_6) == 0x00)
	{
		SysCtlDelay(10*(SysCtlClockGet() / 3000)); 					// ʱԼ10ms
		while (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_6) == 0x00); 		// ȴKEY̧
		SysCtlDelay(10*(SysCtlClockGet() / 3000)); 					// ʱԼ10msɼ

		// 	do something

		return 0x01;
	}

	if (GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_7) == 0x00)
	{
		SysCtlDelay(10*(SysCtlClockGet() / 3000)); 					// ʱԼ10ms
		while (GPIOPinRead(GPIO_PORTC_BASE, GPIO_PIN_7) == 0x00); 		// ȴKEY̧
		SysCtlDelay(10*(SysCtlClockGet() / 3000)); 					// ʱԼ10msɼ

		// 	do something

		return 0x02;
	}

//	if (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7) == 0x00)
//	{
//		SysCtlDelay(10*(SysCtlClockGet() / 3000)); 					// ʱԼ10ms
//		while (GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7) == 0x00); 		// ȴKEY̧
//		SysCtlDelay(10*(SysCtlClockGet() / 3000)); 					// ʱԼ10msɼ
//		return 0x04;
//
//
//	}

	return 0;
}

