
/*******************************************************
* 
* These pograms are for LT7689 GPIO only, Not for LeveTop's other MCU  
*
* 
* LT268C avaulable GIPI pin GINT[0~7], GINT[24~34],GINT[12], GINT[13], GINT[15]
*
********************************************************/

#include "type.h"
#include "eport_drv.h"
#include "eport_reg.h"

#include "lt_api.h"
#include "gpio_drv.h"


static u8 CheckAvailablePin(u8 pinx)
{
	if (pinx>=EPORT_PIN1&&pinx<=EPORT_PIN5) return(0); 
	else if ((pinx>=EPORT_PIN9&&pinx<=EPORT_PIN11)||(pinx>=EPORT_PIN13&&pinx<=EPORT_PIN15)) return (1);

	return (0xFF);
}

static void SWAPCR_Set_ForPin(u8 pinx)
{
	if ((pinx >= EPORT_PIN9) && (pinx <= EPORT_PIN11))
	{
		*(volatile unsigned int *)(SWAPCR) |= (1 << 0);
	}	

	if ((pinx >= EPORT_PIN38) && (pinx <= EPORT_PIN39))
	{
		*(volatile unsigned int *)(SWAPCR) |= (1 << 2);
	}
	if ((pinx >= EPORT_PIN32) && (pinx <= EPORT_PIN37))
	{
		*(volatile unsigned int *)(SWAPCR) |= (1 << 7);
	}	
	if ((pinx >= EPORT_PIN26) && (pinx <= EPORT_PIN31))
	{
		*(volatile unsigned int *)(SWAPCR) |= (1 << 12);
	}	
	if ((pinx >= EPORT_PIN22) && (pinx <= EPORT_PIN25))
	{
		*(volatile unsigned int *)(SWAPCR) |= (1 << 13);
	}
	if ((pinx >= EPORT_PIN18) && (pinx <= EPORT_PIN21))
	{
		*(volatile unsigned int *)(SWAPCR) |= (1 << 14);
	}	
	if ((pinx >= EPORT_PIN16) && (pinx <= EPORT_PIN17))
	{
		*(volatile unsigned int *)(SWAPCR) |= (1 << 15);
	}		
	
	
	if ((pinx >= EPORT_PIN6) && (pinx <= EPORT_PIN7))
	{
		*(volatile unsigned int *)(SWAPCR) &= ~(1 << 4);
		if (pinx >= EPORT_PIN6) *(volatile unsigned int *)(SWAPCR) &= ~(1 << 22);
		else *(volatile unsigned int *)(SWAPCR) &= ~(1 << 23);
	}
	
	if ((pinx >= EPORT_PIN14) && (pinx <= EPORT_PIN15))
	{
		*(volatile unsigned int *)(SWAPCR) &= ~(1 << 1);
	}
	
	if (pinx == EPORT_PIN13) 
	{
		*(volatile unsigned int *)(SWAPCR) &= ~(1 << 17);
		*(volatile unsigned int *)(SWAPCR) &= ~(1 << 21);
	}
	if (pinx == EPORT_PIN14) *(volatile unsigned int *)(SWAPCR) &= ~(1 << 18);
	if (pinx == EPORT_PIN15) *(volatile unsigned int *)(SWAPCR) &= ~(1 << 19);
	if (pinx == EPORT_PIN12) *(volatile unsigned int *)(SWAPCR) &= ~(1 << 20);

}

static void SWAPCR_Set_ForPort(u8 portx)
{
	if (portx==0) 
	{
		*(volatile unsigned int *)(SWAPCR) &= ~(1 << 4);		// Pin6-7
		*(volatile unsigned int *)(SWAPCR) &= ~(1 << 22);		// Pin6
		*(volatile unsigned int *)(SWAPCR) &= ~(1 << 23);		// Pin7
	}
	
	if (portx==1) 
	{
		*(volatile unsigned int *)(SWAPCR) |= (1 << 0);			// Pin9-11
		*(volatile unsigned int *)(SWAPCR) &= ~(1 << 1);		// Pin14,Pin15
		*(volatile unsigned int *)(SWAPCR) &= ~(0x1F << 17);	// Pin12-15
	}
	if (portx==2)
	{
		*(volatile unsigned int *)(SWAPCR) |= (0x03 << 14);	// Pin16~21
		*(volatile unsigned int *)(SWAPCR) |= (0x01 << 13);	// Pin21~23 conflict with Pin24,25
	}
	if (portx==3)
		*(volatile unsigned int *)(SWAPCR) |= (0x03 << 12);	// Pin24-31 conflict with Pin22,23
	
	if (portx==4)
	{
		*(volatile unsigned int *)(SWAPCR) |= (0x01 << 7);		// Pin32-37
		*(volatile unsigned int *)(SWAPCR) |= (0x01 << 2);		// Pin38-39
	}
	
	
}

// ------------------------------------------------------
// Indivisual GPIO pin configure
// Input : 1. pinx = 1,2,3,4,5:EPORT; =9,10,11,13,14,15: EPORT1  
//         2. dir  = 0: Input;        =1: Output
//         3. pull = 0: Pull-down;    =1: pull-up =2: Open drain
//
// ------------------------------------------------------
void GPIOPin_Init(u8 pinx, bool dir,u8 pull)
{
	u8 bitPos=pinx%8;
	u8 portx=pinx/8;
	
	EPORT_TypeDef *EPORTx;
	
	if (portx==0) EPORTx=EPORT0;
	else if (portx==1) EPORTx=EPORT1;
	else if (portx==2) EPORTx=EPORT2;
	else if (portx==3) EPORTx=EPORT3;
	else EPORTx=EPORT4;
	
	SWAPCR_Set_ForPin(pinx);
	
	if (dir) EPORTx->EPDDR |= (0x01<<bitPos);
	else EPORTx->EPDDR &= ~(0x01<<bitPos);
	
	if (pull) EPORTx->EPPUER |= (0x01<<bitPos);
	else EPORTx->EPPUER &= ~(0x01<<bitPos);

}   

// ------------------------------------------------------
// Indivisual GPIO pin configure 
// Input : 1. portx    = 0: EPORT;     =1: EPORT1  
//         2. dir      = 0: Input;     =1: Output (8 bits for 8 GPIO pins) 
//         3. pull     = 0: Pull-down; =1: pull-up, =2: Open drain (8 bits for 8 GPIO pins)
//
// ------------------------------------------------------
void GPIOPort_Init(u8 portx, u8 dir, u8 pull)
{
	SWAPCR_Set_ForPort(portx);
	
	EPORT_TypeDef *EPORTx;
	
	if (portx==0) EPORTx=EPORT0;
	else if (portx==1) EPORTx=EPORT1;
	else if (portx==2) EPORTx=EPORT2;
	else if (portx==3) EPORTx=EPORT3;
	else EPORTx=EPORT4;
	
	EPORTx->EPDDR=dir;
	EPORTx->EPPUER=pull;

}

// ------------------------------------------------------
// Get a GPIO pin state
// Input : pinx = 0~15  
//       
// Output: Pin's state
// ------------------------------------------------------
bool GPIOPin_Read(u8 pinx)
{
	u8 bitPos=pinx%8;
	u8 portx=pinx/8;
	
	EPORT_TypeDef *EPORTx;
	
	if (portx==0) EPORTx=EPORT0;
	else if (portx==1) EPORTx=EPORT1;
	else if (portx==2) EPORTx=EPORT2;
	else if (portx==3) EPORTx=EPORT3;
	else EPORTx=EPORT4;
	
	return((EPORTx->EPPDR&(0x01<<bitPos))>>bitPos);		
}

// ------------------------------------------------------
// Set a GPIO pin state
// Input : pinx  = 0~15  
//         state    
// Output: none
// ------------------------------------------------------
void GPIOPin_Write(u8 pinx, bool state)
{
	u8 bitPos=pinx%8;
	u8 portx=pinx/8;
	
	EPORT_TypeDef *EPORTx;
	
	if (portx==0) EPORTx=EPORT0;
	else if (portx==1) EPORTx=EPORT1;
	else if (portx==2) EPORTx=EPORT2;
	else if (portx==3) EPORTx=EPORT3;
	else EPORTx=EPORT4;
	
	if (state) EPORTx->EPDR |=(0x01<<bitPos);
	else EPORTx->EPDR &=~(0x01<<bitPos);

}

// ------------------------------------------------------
// Get a GPIO port state
// Input : 1. portx    = 0: EPORT  =1: EPORT1  
//         
// Output: Port state
// ------------------------------------------------------
u8 GPIOPort_Read(u8 portx)
{
	EPORT_TypeDef *EPORTx;
	
	if (portx==0) EPORTx=EPORT0;
	else if (portx==1) EPORTx=EPORT1;
	else if (portx==2) EPORTx=EPORT2;
	else if (portx==3) EPORTx=EPORT3;
	else EPORTx=EPORT4;
	
	return(EPORTx->EPPDR);			
}

// ------------------------------------------------------
// Set a GPIO port state
// Input : 1. portx    = 0: EPORT  =1: EPORT1  
//         2. state    = (one bit for one pin)
//
// ------------------------------------------------------
void GPIOPort_Write(u8 portx, u8 state)
{
	EPORT_TypeDef *EPORTx;
	
	if (portx==0) EPORTx=EPORT0;
	else if (portx==1) EPORTx=EPORT1;
	else if (portx==2) EPORTx=EPORT2;
	else if (portx==3) EPORTx=EPORT3;
	else EPORTx=EPORT4;
	
	EPORTx->EPDR=state;
}


// ===============================================
// GINT 
// 
// ------------------------------------------------------
// Indivisual GPIO pin configure
// Input : 1. pinx         = 0~15 
//         2. intMode  =0: Low level trigger, 
//                     =1: Rising edge, 
//                     =2: falling edge, 
//                     =3: Rising and falling edge trigger, 
//                     =4: High level trigger 
//         
// ------------------------------------------------------
typedef enum
{
    LOW_LEVELTRIGGER = 0,
    RISING_EDGETRIGGER =1,
    FALLIN_GEDGETRIGGER =2,
    RISING_FALLING_EDGETRIGGER=3,
	 HIGH_LEVELTRIGGER=4,

}GINT_TRIGGER_MODE;


void GINTPin_Init(u8 pinx, u8 intMode,bool intEnable)
{
	u8 bitPos=pinx%8;
	u8 portx=pinx/8;
	u8 level=intMode/4;	// 4 level=0: low level trigger, =1: hith level trigger	
	intMode=intMode%4;	// %5 
	
	EPORT_TypeDef *EPORTx;
	
	if (portx==0) EPORTx=EPORT0;
	else if (portx==1) EPORTx=EPORT1;
	else if (portx==2) EPORTx=EPORT2;
	else if (portx==3) EPORTx=EPORT3;
	else EPORTx=EPORT4;

	SWAPCR_Set_ForPin(pinx);
	
	EPORTx->EPDDR &= ~(0x01<<bitPos);					// pinx as input
	EPORTx->EPPAR &= ~(0x03<<(bitPos*2));				// clear pinx int mode 
	EPORTx->EPPAR |= (intMode<<(bitPos*2));			// set new int mode
	if (level) EPORTx->EPLPR |= (0x01<<bitPos);		// set level trigger register 
	else EPORTx->EPLPR &= ~(0x01<<bitPos);

	if(((pinx>>3) == 0) ||((pinx>>3) == 2)) //EPORT0 or EPORT2
		NVIC_Init(3, 3, (EPORT0_0_IRQn) + (pinx&7), 2);
	else	// EPORT 1, EPORT3, and EPORT4
		NVIC_Init(3, 3, (EPORT1_0_IRQn) + (pinx&7), 2);
		
	if (intEnable) EPORTx->EPIER |= (0x01<<bitPos);
	else EPORTx->EPIER &= ~(0x01<<bitPos);
} 


