/******************** (C) COPYRIGHT 2020 SONiX *******************************
* COMPANY:			SONiX
* DATE:					2020/06
* AUTHOR:				SA1
* IC:						SN32F780/790
* DESCRIPTION:	EBI related functions.
*____________________________________________________________________________
*	REVISION	Date				User	Description
*	1.0				2020/06/24	SA1		First release
*
*____________________________________________________________________________
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS TIME TO MARKET.
* SONiX SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL 
* DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE
* AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN 
* IN CONNECTION WITH THEIR PRODUCTS.
*****************************************************************************/

/*_____ I N C L U D E S ____________________________________________________*/
#include <SN32F780.h>
#include "EBI.h"
#include "..\..\Utility\Utility.h"

/*_____ D E C L A R A T I O N S ____________________________________________*/

/*_____ D E F I N I T I O N S ______________________________________________*/

/*_____ M A C R O S ________________________________________________________*/

/*_____ F U N C T I O N S __________________________________________________*/

/*****************************************************************************
* Function		: EBI8080_Init
* Description	: Initialization of EBI 8080
* Input			: bBank:Bank0/1/2/3, 	bMode:A1D8/A1D16
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void EBI_8080Init(uint8_t bBank, uint8_t bMode)
{ 
	SN_SYS1->AHBCLKEN_b.EBICLKEN = 1;  //enable EBI AHB clock	 
	switch (bBank)
	{
		case 0:
					SN_EBI->CTRL_b.BANK0EN = EBI_ENABLE_BANK;
					SN_EBI->CTRL_b.MODE0 = EBI_MODE_8080;
					SN_EBI->TREAD0_b.RDSTRB = 0x3;
					SN_EBI->TREAD0_b.RDHOLD = 0x0;
					SN_EBI->TREAD0_b.RDSETUP = 0x0;								
					SN_EBI->TWRITE0_b.WESTRB = 0x3;
					SN_EBI->TWRITE0_b.WEHOLD = 0x0;
					SN_EBI->TWRITE0_b.WESETUP = 0x0;
					SN_EBI->CTRL_b.IDLETIME = 0x1;
					SN_EBI->CTRL_b.BK8080MODE0 = bMode;
		
					if(bMode == EBI_BK8080MODE_A1D8)
					{
						wREG_Add = EBI_BANK0_ADD;
						wRAM_Add = EBI_BANK0_ADD+1;						
					}
					if(bMode == EBI_BK8080MODE_A1D16)
					{
						wREG_Add = EBI_BANK0_ADD;
						wRAM_Add = EBI_BANK0_ADD+2;
					}
		break;		
		case 1:
					SN_EBI->CTRL_b.BANK1EN = EBI_ENABLE_BANK;
					SN_EBI->CTRL_b.MODE1 = EBI_MODE_8080;	
					SN_EBI->TREAD1_b.RDSTRB = 0x3;
					SN_EBI->TREAD1_b.RDHOLD = 0x0;
					SN_EBI->TREAD1_b.RDSETUP = 0x0;								
					SN_EBI->TWRITE1_b.WESTRB = 0x3;
					SN_EBI->TWRITE1_b.WEHOLD = 0x0;
					SN_EBI->TWRITE1_b.WESETUP = 0x0;
					SN_EBI->CTRL_b.IDLETIME = 0x1;
					SN_EBI->CTRL_b.BK8080MODE1 = bMode;	
		
					if(bMode == EBI_BK8080MODE_A1D8)
					{
						wREG_Add = EBI_BANK1_ADD;
						wRAM_Add = EBI_BANK1_ADD+1;						
					}
					if(bMode == EBI_BK8080MODE_A1D16)
					{
						wREG_Add = EBI_BANK1_ADD;
						wRAM_Add = EBI_BANK1_ADD+2;
					}				
		break;
		case 2:
					SN_EBI->CTRL_b.BANK2EN = EBI_ENABLE_BANK;
					SN_EBI->CTRL_b.MODE2 = EBI_MODE_8080;
					SN_EBI->TREAD2_b.RDSTRB = 0x3;
					SN_EBI->TREAD2_b.RDHOLD = 0x0;
					SN_EBI->TREAD2_b.RDSETUP = 0x0;								
					SN_EBI->TWRITE2_b.WESTRB = 0x3;
					SN_EBI->TWRITE2_b.WEHOLD = 0x0;
					SN_EBI->TWRITE2_b.WESETUP = 0x0;
					SN_EBI->CTRL_b.IDLETIME = 0x1;
					SN_EBI->CTRL_b.BK8080MODE2 = bMode;	
		
					if(bMode == EBI_BK8080MODE_A1D8)
					{
						wREG_Add = EBI_BANK2_ADD;
						wRAM_Add = EBI_BANK2_ADD+1;						
					}
					if(bMode == EBI_BK8080MODE_A1D16)
					{
						wREG_Add = EBI_BANK2_ADD;
						wRAM_Add = EBI_BANK2_ADD+2;
					}
		break;
		case 3:
					SN_EBI->CTRL_b.BANK3EN = EBI_ENABLE_BANK;
					SN_EBI->CTRL_b.MODE3 = EBI_MODE_8080;
					SN_EBI->TREAD3_b.RDSTRB = 0x3;
					SN_EBI->TREAD3_b.RDHOLD = 0x0;
					SN_EBI->TREAD3_b.RDSETUP = 0x0;								
					SN_EBI->TWRITE3_b.WESTRB = 0x3;
					SN_EBI->TWRITE3_b.WEHOLD = 0x0;
					SN_EBI->TWRITE3_b.WESETUP = 0x0;
					SN_EBI->CTRL_b.IDLETIME = 0x1;
					SN_EBI->CTRL_b.BK8080MODE3 = bMode;
		
					if(bMode == EBI_BK8080MODE_A1D8)
					{
						wREG_Add = EBI_BANK3_ADD;
						wRAM_Add = EBI_BANK3_ADD+1;						
					}
					if(bMode == EBI_BK8080MODE_A1D16)
					{
						wREG_Add = EBI_BANK3_ADD;
						wRAM_Add = EBI_BANK3_ADD+2;
					}
		break;		
	
		default:
		break;
	}	
	
	return;
}
/*****************************************************************************
* Function		: EBI_8080DMA
* Description	: Initialization of EBI DMA
* Input			: bSPI:SPI0/1,   bBank:Bank0/1/2/3, 	bInterruptMode: 1:test interrupt/0:test polling
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void EBI_8080DMA(uint8_t bSPI, uint8_t bBANK, uint8_t bInterruptMode)
{
	SN_SYS1->AHBCLKEN_b.EBICLKEN = 1;  //enable EBI AHB clock	
	if(bInterruptMode)
	{
		NVIC_ClearPendingIRQ(EBI_IRQn);
		NVIC_EnableIRQ(EBI_IRQn);
		SN_EBI->IE_b.DMAHTIE = 1;
		SN_EBI->IE_b.DMATCIE = 1;
  }

	SN_EBI->DMACTRL_b.SPISELECT = bSPI;
	SN_EBI->DMACTRL_b.BANKSELECT = bBANK;		
}	
/*****************************************************************************
* Function		: EBI_Clear_Intflag
* Description	: clear the flag of EBI interrupt
* Input				: None
* Output			: None
* Return			: None
* Note				: None
*****************************************************************************/
void EBI_Clear_Intflag(void)
{
	SN_EBI->IC |= (mskEBI_RIS_ARDYTOIC
								|mskEBI_RIS_ACCDISIC
								|mskEBI_RIS_SMRSTIC
								|mskEBI_RIS_RWERRIC
								|mskEBI_RIS_DMAHTIC
								|mskEBI_RIS_DMATCIC);
	return;
}

/*****************************************************************************
* Function		: EBI_Interrupt_Enable
* Description	: enable the interrupt of EBI
* Input				: None
* Output			: None
* Return			: None
* Note				: None
*****************************************************************************/
void EBI_Interrupt_Enable(void)
{
	NVIC_ClearPendingIRQ(EBI_IRQn);
	NVIC_EnableIRQ(EBI_IRQn);
	SN_EBI->IE |= (mskEBI_RWERREN_EN
								|mskEBI_SMRSTEN_EN
								|mskEBI_ACCDISEN_EN
								|mskEBI_ARDYTOEN_EN);
	return;
}

/*****************************************************************************
* Function		: EBI_Interrupt_Disable
* Description	: disable the interrupt of EBI
* Input				: None
* Output			: None
* Return			: None
* Note				: None
*****************************************************************************/
void EBI_Interrupt_Disable(void)
{
	NVIC_ClearPendingIRQ(EBI_IRQn);
	NVIC_DisableIRQ(EBI_IRQn);
	SN_EBI->IE |= (mskEBI_RWERREN_DIS
								|mskEBI_SMRSTEN_DIS
								|mskEBI_ACCDISEN_DIS
								|mskEBI_ARDYTOEN_DIS);
	return;
}

/*****************************************************************************
* Function		: EBI_8080Write_CMD_16B
* Description	: write command by EBI 8080
* Input				: command
* Output			: None
* Return			: None
* Note				: None
*****************************************************************************/
void EBI_8080Write_CMD_16B(uint16_t hwCMD)
{   
	*(uint16_t *)(wREG_Add) = hwCMD;
}

/*****************************************************************************
* Function		: EBI_8080Write_Data_16B
* Description	: write data by EBI 8080
* Input				: data
* Output			: None
* Return			: None
* Note				: None
*****************************************************************************/
void EBI_8080Write_Data_16B(uint16_t hwData)
{	 
	*(uint16_t *)(wRAM_Add) = hwData;		 
}

/*********************************************************************************************************
* Function Name: EBI_IRQHandler
* Description: EBI interrupt service routine
* Input: None
* Output: None
* Return: None
*********************************************************************************************************/
__irq	void EBI_IRQHandler (void)
{
	uint16_t hwRIS_buf;
	hwRIS_buf = SN_EBI->RIS;
	if ((hwRIS_buf & mskEBI_RIS_DMATCIF) ==  mskEBI_RIS_DMATCIF) 	//DMATCIF
	{
		SN_EBI->IC_b.DMATCIC = 1;
		bDMATC_Flag = 1;
	}
	if ((hwRIS_buf & mskEBI_RIS_DMAHTIF) ==  mskEBI_RIS_DMAHTIF) 	//DMAHTIF
	{
		SN_EBI->IC_b.DMAHTIC = 1;
		bDMAHT_Flag = 1;
	}
	if ((hwRIS_buf & mskEBI_RIS_RWERRIF) ==  mskEBI_RIS_RWERRIF) 				//RWERRIF
	{
		SN_EBI->IC_b.RWERRIC = 1;
		bRWERR_Flag = 1;
	}
	if ((hwRIS_buf & mskEBI_RIS_ARDYTOIF) ==  mskEBI_RIS_ARDYTOIF) 	//ARDYTOIF
	{
		SN_EBI->IC_b.ARDYTOIC = 1;
		bARDYTO_Flag = 1;
	}
	if ((hwRIS_buf & mskEBI_RIS_SMRSTIF) ==  mskEBI_RIS_SMRSTIF) 		//SMRSTIF
	{
		SN_EBI->IC_b.SMRSTIC = 1;
		bSMRST_Flag = 1;
	}
	if ((hwRIS_buf & mskEBI_RIS_ACCDISIF) ==  mskEBI_RIS_ACCDISIF) 	//ACCDISIF
	{
		SN_EBI->IC_b.ACCDISIC = 1;
		bACCDIS_Flag = 1;
	}
}
