/*
*Copyright ,2023 , NANOCHAP
*File name:   ENS1_SPI.C         
*Author:      
*Version:     V1.0 
*Date:        2023-11-                  
*Description:  
*Function List: 
    
History: 
	1.V1.0
	Date:          
	Author: 
	Modification: 2023-11-15
*/  

#include "ENS1_SPI.h"
#include "ENS1_GPIO.h"
/*---------------------------------------------------fifo????????--------------------------------------------------*/
/* Clear FIFO and reset to 0 */
uint8_t CLR_TX_FIFO( CMSDK_SPI_TypeDef* SPIx) 
{
	return (uint8_t)(SPIx->FCR>>8 & 0x1);
}

uint8_t CLR_RX_FIFO(CMSDK_SPI_TypeDef* SPIx)   
{
	return (uint8_t)(SPIx->FCR>>1 & 0x1);
}
/*FIFO ?????*/
uint8_t RX_FIFO_LEN(CMSDK_SPI_TypeDef* SPIx)  
{
	return (uint8_t)(((SPIx->FCR & 0x1) == 0x1) ? ((uint8_t)((SPIx->FSR & 0x001f0000)>>16)):0);        //??????????FIFO???????
}

uint8_t TX_FIFO_LEN(CMSDK_SPI_TypeDef* SPIx)    
{
	return (uint8_t)(((SPIx->FCR & 0x1) == 0x1) ? ((uint8_t)((SPIx->FSR & 0x00001f00)>>8)):0);	       //??????????FIFO???????
}	

SPI_BUSY_STATE BUSY_STATE(CMSDK_SPI_TypeDef* SPIx) 
{
	return (SPI_BUSY_STATE)((((SPIx->FSR & 0x10) >> 4)==1) ? ( BUSY ) : ( NOTBUSY ));           //??????SPI????
}	

uint8_t  RX_FIFO_FULL(CMSDK_SPI_TypeDef* SPIx) 
{
	return 	(uint8_t)((((SPIx->FSR & 0x8)>> 3 )==1) ?  (1) : (0)) ;          //??????FIFO????????
}	

uint8_t RX_FIFO_EMPTY(CMSDK_SPI_TypeDef* SPIx) 
{	
	return 	(uint8_t)((((SPIx->FSR & 0x4) >> 2)==1) ?    (1) : (0)  ) ;          //??????FIFO???????
}	

uint8_t TX_FIFO_FULL(CMSDK_SPI_TypeDef* SPIx)  
{
	return 	(uint8_t)((((SPIx->FSR & 0x2) >> 1)==1) ?  (1) : (0)) ;         //???????FIFO????????
}	

uint8_t TX_FIFO_EMPTY(CMSDK_SPI_TypeDef* SPIx)  
{
	return (uint8_t)(((SPIx->FSR & 0x1)==1) ? (1) : (0)) ;          //???????FIFO???????
}




/*FIFO???/DMA???*/ 
uint8_t SPI_FIFO_STATE(CMSDK_SPI_TypeDef* SPIx)  //??FIFO????
{
	return (uint8_t)(SPIx->FCR & 0x1) ;
}
uint8_t SPI_FIFO_ENABLE(CMSDK_SPI_TypeDef* SPIx )
{	
	SPIx->FCR |= 0x1;
	return   0;//(uint8_t)(SPIx->FCR & 0x1) ;
}

uint8_t SPI_FIFO_DISABLE(CMSDK_SPI_TypeDef* SPIx )
{
	SPIx->FCR &=~ 0x1;
	return (uint8_t)(SPIx->FCR & 0x1) ;
}

uint8_t SPI_FIFODMA_SET(CMSDK_SPI_TypeDef* SPIx ,bool TXDMA_SET ,bool RXDMA_SET)
{
	if(TXDMA_SET == true)
		SPIx->CTRL2 |= (1<<5);
	else if(TXDMA_SET == false)
		SPIx->CTRL2 &=~ (1<<5);
	
	if(TXDMA_SET == true)
		SPIx->CTRL2 |= (1<<4);
	else if(TXDMA_SET == false)
		SPIx->CTRL2 &=~ (1<<4);
	return (uint8_t)((SPIx->CTRL2>>4)&0x3);
}

/*------------------------------------------------------fifo???????��--------------------------------------------------*/

/*----------------------------------------------------------SPI????-------------------------------------------------------*/
//????????SPI??
uint8_t READ_SPI_MODE(CMSDK_SPI_TypeDef* SPIx)
{
	return ((SPIx->CTRL1 & 0x7000) >> 12); 
}

//NSS??????
uint8_t SPI_NSS_CHANNEL(CMSDK_SPI_TypeDef* SPIx ,NSS_CHANNEL_SEL NSSx ,FunctionalState ENorDIS)
{
	if(ENorDIS == ENABLE)
		SPIx->CTRL2 |= ( 1 << NSSx );
	else
		SPIx->CTRL2 &=~ ( 1 << NSSx);
	
	return (uint8_t)((SPIx->CTRL2 & 0x0f00) >> 8);
}

//spi?????????
uint8_t SPI_Config_init(CMSDK_SPI_TypeDef* SPIx ,
							struct SPI_ModeConfig_Struct SPI_Config,
								struct SPI_FIFO_Struct FIFO_Struct) 
{
/*1??GPIO ALTER*/
	if(SPIx == CMSDK_SPI1)
	{
		
		
		GPIO_AltFunction(GPIO_16 , ALT_FUNC2);
		GPIO_AltFunction(GPIO_17 , ALT_FUNC2);
		GPIO_AltFunction(GPIO_18 , ALT_FUNC2);
		GPIO_AltFunction(GPIO_19 , ALT_FUNC2);
	
	}
	else if(SPIx == CMSDK_SPI0)
	{   
		
		
		GPIO_AltFunction(GPIO_8, ALT_FUNC1);
		GPIO_AltFunction(GPIO_9, ALT_FUNC1);
		GPIO_AltFunction(GPIO_10,ALT_FUNC1);
		GPIO_AltFunction(GPIO_11,ALT_FUNC1);
	}

/*
  2??��SPI_CTRL1?????
	??1??????????????BAUD_RATE[2:0]
	??2???????????????�� CPOL and CPHA bits
	??3????????? BIDI_EN, BIDI_MODE, UNIDI_MODE bits
	??4??????LSB_SEL��??????????
	??5?????????NSS_TOGGLE??NSS_MST_CTRL??NSS_MST_SW bits?????NSS??????  bit11 9 8
	??6?????????MST_SLV_SEL��????????????
*/
	 SPIx->CTRL1 = (SPIx->CTRL1&~ 0xffff) | ( SPI_Config.BAUD_FPCLKdivx << 4);
	 SPIx->CTRL1 |= (SPI_Config.SPI_MODE << 2);
	 SPIx->CTRL1 |= (SPI_Config.SPI_TRANS_MODE << 12 );
	 SPIx->CTRL1 &=~ (0x1 << 7);  //???????????
	 SPIx->CTRL1 &=~ (0x1 << 8);  //???????????
	 SPIx->CTRL1 &=~ (1 << 11);
	 SPIx->CTRL1 |= (1 << 11) ;  // ??????????NSS
	
	 if(SPI_Config.MS_SEL == MASTER)
	 {
		 SPIx->CTRL1 |= (1<<1);
	 }
	 else 
	 {
		SPIx->CTRL1 &=~ (1<<1);
	 }
/*
  3??��SPI_CTRL2?????
	??1??????CHAR_LEN[3:0]��???????????????
	??2?????NSS???? NSS0_EN, NSS1_EN, NSS2_EN
	??3????????????????????RX????????? SAMP_PHASE(1:0)��
	??4?????????C2T_DELAY??T2C_DELAY��???????????��?????????????C2T/T2C???
	??5?????????TXDMA_EN??RXDMA_EN��???????FIFO????TX/RX DMA??
*/
	SPIx->CTRL2 =  (SPIx->CTRL2&~ 0xffff);
	if(SPI_Config.CHAR_LEN < 4)
	{
 
	}
	else if((SPI_Config.CHAR_LEN >= 4) && (SPI_Config.CHAR_LEN  < 17))
	{
		SPIx->CTRL2 |= (SPI_Config.CHAR_LEN -1);	 
	}
	else 
	{
		
	}
	SPI_NSS_CHANNEL(SPIx ,SPI_Config.NSSx ,ENABLE);
	//rx???????��?? ??????????????��??????normal
	//C2T_DELAY ,????????????��
	//T2C_DELAY, ????????????��
	if(SPI_Config.MS_SEL == MASTER)
	{
		SPIx->CTRL2 |= (SPI_Config.SAMP_PHASE << 6);
		//T2C ??Transmit-end-to-chip-inactive ????????????1T SCK
		//C2T ??Chip-select-active-to-transmit-start  ????? ???1T SCK ,????????????????????
	}
	
	
/*
	4??��FIFO ?????
	??1??????TX_FIFO_TH??RX_FIFO_TH?????��?????????
	??2?????????TX_FIFO_CLR??RX_FIFO_CLR��???TX/RX FIFO
	??3?????????fif_en��???????FIFO??
*/	
	SPIx->FCR |= (FIFO_Struct.TX_FIFO_TH << 9 );
	SPIx->FCR |= (FIFO_Struct.RX_FIFO_TH << 2 );
	CLR_TX_FIFO(SPIx) ;
    CLR_RX_FIFO(SPIx) ;
	if(FIFO_Struct.FIFO_ENABLE_SET == true)
		SPI_FIFO_ENABLE(SPIx);
	//SPI_FIFODMA_SET(SPIx ,FIFO_Struct.TXDMA_SET ,FIFO_Struct.RXDMA_SET);	
	return 0;
}

/*---------------------------------------------SPI????????-------------------------------------------------*/
uint8_t SPI_START(CMSDK_SPI_TypeDef* SPIx )
{
	SPIx->CTRL1 |= (1);
	return (uint8_t)(SPIx->CTRL1 & 0x1);
}

uint8_t  SPI_STOP(CMSDK_SPI_TypeDef* SPIx)
{	
	if((READ_SPI_MODE(SPIx)==(L2_UniDirect_R & 0x7)) || (READ_SPI_MODE(SPIx)==(L1_BiDirect_R & 0x7)))
	{
		if(SPI_FIFO_STATE(SPIx) == 1)
		{	
			//?? RX??FIFO ??? FIFO????? 0
			while((RX_FIFO_LEN(SPIx) != 0)  || (BUSY_STATE(SPIx) == BUSY))
			{
				//save_data = READ_SPI_RCVBuff(SPIx);
			}
			SPIx->CTRL1 &=~ (1);
		}	
		else if(SPI_FIFO_STATE(SPIx) == 0)
		{
			while(BUSY_STATE(SPIx) == BUSY);
			SPIx->CTRL1 &=~ (1);
		}
	}
	else 
	{	
		if(SPI_FIFO_STATE(SPIx) == 1)
		{
			while((TX_FIFO_LEN(SPIx)!= 0) || (BUSY_STATE(SPIx) == BUSY));
			SPIx->CTRL1 &=~ (1);
			//?? RX??FIFO ??? FIFO????? 0
			while(RX_FIFO_LEN(SPIx) != 0)
			{
				uint16_t save_data = READ_SPI_RCVBuff(SPIx);
			}
		}	
		else if(SPI_FIFO_STATE(SPIx) == 0)
		{
			while(BUSY_STATE(SPIx) == BUSY);
			SPIx->CTRL1 &=~ (1);
		}
	}
	return (uint8_t)(SPIx->CTRL1*0x1);
}

/*-----------------------------------------?? / �� SPI BUFFER??????-------------------------------------------------*/
//????????????? ???16bits
uint16_t READ_SPI_RCVBuff(CMSDK_SPI_TypeDef* SPIx)
{	
	return (uint16_t)(SPIx->RBR & 0xffff);
}

//��????
void WRITE_SPI_THRBuff(CMSDK_SPI_TypeDef* SPIx,uint8_t data)
{	
	SPIx->THR = data;
	while(BUSY_STATE(SPIx) == BUSY);
}

/*------------------------------------------------------SPI?��?------------------------------------------------------*/
uint8_t SPI_INT_SET(IRQn_Type IRQn, bool SPI_INT_ENABLE, uint8_t SPI_INT_BIT_SET)
{
	NVIC_DisableIRQ(IRQn);
	NVIC_ClearPendingIRQ(IRQn);	
	if(IRQn == SPI0_IRQn)
	{
		CMSDK_SPI0->IER = ((CMSDK_SPI0->IER &~ (0xff)) | SPI_INT_BIT_SET);
	}
	else if(IRQn == SPI1_IRQn)
	{
		CMSDK_SPI1->IER = ((CMSDK_SPI0->IER &~ (0xff)) | SPI_INT_BIT_SET);
	}
	
	if(SPI_INT_ENABLE == true)
	{
		NVIC_EnableIRQ(IRQn); 
	}
	else 
	{
		NVIC_DisableIRQ(IRQn); 
	}	
	return 0;
}

//?��????????
/*
?��????????????
1??????????? ???? ?��?????????????????
2??????????? ??? ?��??????????
3?????????��??
4????????????? ?��?
5?????????????? ?��?
*/
void SPI1_Handler(void)
{
	NVIC_ClearPendingIRQ(SPI1_IRQn);
	uint8_t read_fifo=0;
	if((CMSDK_SPI1->INTSTATUS & 0x10 )== UNDERRUN_INT)  //????-???????????????????????
	{
		CMSDK_SPI1->INTCLEAR |= (1<<4);        //????��?
	}
	if((CMSDK_SPI1->INTSTATUS & 0x8) ==OVERRUN_INT)  
	{
		CMSDK_SPI1->INTCLEAR |= (1<<3); 
	}	
	if((CMSDK_SPI1->INTSTATUS& 0x4) ==CMPL_INT)
	{
		CMSDK_SPI1->INTCLEAR |= (1<<2); 
	}	
	if((CMSDK_SPI1->INTSTATUS &0x2) ==TXE_INT)  
	{
		
	}	
	if((CMSDK_SPI1->INTSTATUS & 1)== RXNE_INT)  
	{
		
		while(!RX_FIFO_EMPTY(CMSDK_SPI1))   
		{		
			read_fifo = READ_SPI_RCVBuff(CMSDK_SPI1);
		}
	}
	
	
}

void SPI0_Handler(void)
{
	NVIC_ClearPendingIRQ(SPI0_IRQn);	
	uint8_t read_fifo=0;
	if((CMSDK_SPI0->INTSTATUS & 0x10 )== UNDERRUN_INT)  //????-???????????????????????
	{
		CMSDK_SPI0->INTCLEAR |= (1<<4);        //????��?
	}
	if((CMSDK_SPI0->INTSTATUS & 0x8) ==OVERRUN_INT)  
	{
		CMSDK_SPI0->INTCLEAR |= (1<<3); 
	}	
	if((CMSDK_SPI0->INTSTATUS& 0x4) ==CMPL_INT)
	{
		CMSDK_SPI0->INTCLEAR |= (1<<2); 
	}	
	if((CMSDK_SPI0->INTSTATUS &0x2) ==TXE_INT)  
	{
		
	}	
	if((CMSDK_SPI0->INTSTATUS & 1)== RXNE_INT)  
	{
		
		while(!RX_FIFO_EMPTY(CMSDK_SPI0))    
		{		
			read_fifo = READ_SPI_RCVBuff(CMSDK_SPI0);
		}
	}
}



