/**
  **********************************************************************************
  *@file    SSI_drv.c
  *@author  Product application department
  *@version V1.0
  *@date    2020.03.16
  *@brief   SSI模块DRV层驱动.
  *
  @verbatim
  ===================================================================================
                                  ##### 更新 #####
  ===================================================================================
  [..] 更新时间:
  [..] 更新人:
  [..] 更新内容:
        1. nothing.
  @endverbatim
*/
#include "ssi_drv.h"
#include "common.h"
#include "dma_drv.h"
/**
 *@brief 恢复SSI为默认设置.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@retval 结果 @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef DRV_SSI_DeInit(SSI_TypeDef *pssi)
{   
	  //CPM中复位模块
    if(pssi == SSI1)
		{
			  (*(uint32_t*)(0x40004000+0xb0))|= (1<<25);
		    (*(uint32_t*)(0x40004000+0xb0))&=~(1<<25);
		}
		else
			if(pssi == SSI2)
			{
			  (*(uint32_t*)(0x40004000+0xb0))|= (1<<26);
		    (*(uint32_t*)(0x40004000+0xb0))&=~(1<<26);
			}
			else
			{
			    return DRV_SSI_ERROR;
			}
	 return DRV_SSI_OK;
}

/**
 *@brief 赋予SSI结构体默认值.
 *
 *@param[in] pinit 指向SSI_InitTypeDef结构体的指针;
 *@return 无 @ref 无
 */
void DRV_SSI_StructInit(SSI_InitTypeDef *pinit)
{
    pinit->Format = STD_mode;
    pinit->DFS   = DFS_08_BIT;
		pinit->FRF   = FRF_SPI;
		pinit->SCPH  = SCPH_MIDDLE_BIT;
		pinit->SCPOL = INACTIVE_HIGH;
		pinit->TMOD  = TX_AND_RX;
		pinit->SRL   = NORMAL_MODE;
		pinit->SSTE  = TOGGLE_DISABLE;
		pinit->CFS   = CFS_01_BIT;
		pinit->NDF   = 0;
		pinit->SSI_STD_BaudRatePrescaler = 0xffff;
	  pinit->SSI_DUAL_BaudRatePrescaler = 0xffff;
	  pinit->SSI_QUAD_BaudRatePrescaler = 0xffff;
		pinit->Transfer_start_FIFO_level = 0;
	  pinit->Transmit_FIFO_Threshold = 0;
		pinit->Receive_FIFO_Threshold = 0;
	
	  pinit->Rx_Sample_Delay =  SAMPLE_DELAY_2_0;
	
		pinit->Trans_Type = TT0;
		pinit->Address_Length = ADDR_L0;
		pinit->Instruction_length = INST_L0;
		pinit->WAIT_CYCLES = 0x10;
		pinit->CLK_STRETCH_EN = CLK_STRETCH_DISABLE;
}

/**
  *@brief 获取标志状态.
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  FlagIndex SSI标志索引;
	 *- SSI_FLAG_INDEX_BUSY,
	*- SSI_FLAG_INDEX_TFNF,
	*- SSI_FLAG_INDEX_TFE,
	*- SSI_FLAG_INDEX_RFNE,
	*- SSI_FLAG_INDEX_RFF,
  *@param[out] pflag 标志状态
  *- SET;
  *- REST;
  *@retval 当前状态 @ref DRV_SPI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_GetFlag(SSI_TypeDef *pssi,SSI_FlagIndexTypeDef FlagIndex,FlagStatusTypeDef *pflag)
{

	if((FlagIndex>= SSI_FLAG_INDEX_BUSY) && (FlagIndex<= SSI_FLAG_INDEX_RFF))
	{
		if(pssi->SR&FlagIndex)
			*pflag = SET;
		else
			*pflag = RESET;
	}
	else
	{
		return(DRV_SSI_ERROR);
	}
	
	return(DRV_SSI_OK);
}
/**
 *@brief 使能SSI.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@return 无;
 */
void DRV_SSI_En(SSI_TypeDef *pssi)
{
    _ssi_en(pssi);
}
/**
 *@brief 禁止SSI.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@return 无;
 */
void DRV_SSI_Dis(SSI_TypeDef *pssi)
{
    _ssi_dis(pssi);
}
/**
 *@brief 使能或禁止SSI.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@param[in] NewState 新的状态
 * -ENABLE;
 * -DISABLE;
 *@return 无;
 */
void DRV_SSI_Cmd(SSI_TypeDef *pssi, FunctionalStateTypeDef NewState)
{
    if(NewState ==  ENABLE)
        _ssi_en(pssi);
    else
        _ssi_dis(pssi);
}

/**
 *@brief SSI单线CS初始化.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@param[in] NewState 新的状态
 * -ENABLE;
 * -DISABLE;
 *@return 无;
 */

void DRV_SSI_CS_Init(SSI_TypeDef *pssi)
{
  
	if(pssi == SSI1)
		{
	    (*(volatile unsigned int *)(0x40000000+0x28)) |= 0x01; //spi4使能
	    (*(volatile unsigned char *)(0x4002d000+0x03)) |=  (1<<0);//输出模式
		}
 	else if (pssi == SSI2)
		{
			(*(volatile unsigned int *)(0x40000000+0x28)) |= (0x01<<24); //spi5使能
			(*(volatile unsigned char *)(0x4002e000+0x03)) |=  (1<<0);  //输出模式
		}

}

/**
 *@brief 退出SSI单线CS模式.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@param[in] NewState 新的状态
 * -ENABLE;
 * -DISABLE;
 *@return 无;
 */
void DRV_SSI_CS_DisInit(SSI_TypeDef *pssi)
{
	if(pssi == SSI1)
		{
     (*(volatile unsigned int *)(0x40000000+0x28)) &= ~(0x01);
	  }
 	else if (pssi == SSI2)
		{	
		 (*(volatile unsigned int *)(0x40000000+0x28))  &= ~(0x01<<24);
		}			
}
/**
 *@brief SSI单线CS?.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@param[in] NewState 新的状态
 * -ENABLE;
 * -DISABLE;
 *@return 无;
 */
void DRV_SSI_CS_LOW(SSI_TypeDef *pssi)
{
  if(pssi == SSI1)
		{
			(*(volatile unsigned char *)(0x4002d000+0x05))&= ~(1<<0);
		}
	else if (pssi == SSI2)
	 {
	    (*(volatile unsigned char *)(0x4002e000+0x05))&= ~(1<<0);
	 }
}
/**
 *@brief SSI单线CS拉高.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@param[in] NewState 新的状态
 * -ENABLE;
 * -DISABLE;
 *@return 无;
 */
void DRV_SSI_CS_HIGH(SSI_TypeDef *pssi)
{
  if(pssi == SSI1)
		{
			(*(volatile unsigned char *)(0x4002d000+0x05))|=  (1<<0);
		}
	else if (pssi == SSI2)
	  {
	    (*(volatile unsigned char *)(0x4002e000+0x05))|=  (1<<0);
	  }
}
/**
 *@brief 使能SSI中断.
 *
 *@param[in] pssi 指向SSI_TypeDef的指针;
 *@return 无;
 */
void DRV_SSI_ItEn(SSI_TypeDef *pssi)
{

}
/**
  *@brief SSI 获取当前速率
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@retval 当前速率 @ref uint16_t
  */
uint16_t DRV_Get_SSI_baund(SSI_TypeDef *pssi)
{
	return pssi->BAUDR;
}
/**
  *@brief 获取标志状态.
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  FlagIndex SSI标志索引;
	 *- SSI_FLAG_INDEX_BUSY,
	*- SSI_FLAG_INDEX_TFNF,
	*- SSI_FLAG_INDEX_TFE,
	*- SSI_FLAG_INDEX_RFNE,
	*- SSI_FLAG_INDEX_RFF,
  *@param[in] staus 标志状态
  *- SET;
  *- REST;
  @param[in] timeout 超时时间;
  *@retval 当前状态 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_WaitonFlagTimeout(SSI_TypeDef *pssi,
                                            SSI_FlagIndexTypeDef index,
                                            FlagStatusTypeDef status,
                                            uint32_t timeout)
{
  FlagStatusTypeDef tmp_flag = RESET;
  if(timeout == 0)
	{
	    DRV_SSI_GetFlag(pssi,index,&tmp_flag);
			if(tmp_flag!=status)
			{
				return(DRV_SSI_TIMEOUT);
			}
	}
	else
	{
		while(timeout)
		{
			DRV_SSI_GetFlag(pssi,index,&tmp_flag);
			if(tmp_flag!=status)
			{
				break;
			}
			timeout--;
			if(timeout == 0)
			{
					return(DRV_SSI_TIMEOUT);
			}		
		}
	}
	return DRV_SSI_OK;
}
/**
  *@brief 清空fifo.
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  @param[in] timeout 超时时间;
  *@retval 当前状态 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_clear_fifo(SSI_TypeDef *pssi,uint8_t *status,uint32_t timeout)
{
  FlagStatusTypeDef flag = RESET;
	uint32_t data_reg;

	DRV_SSI_GetFlag(pssi,SSI_FLAG_INDEX_RFNE,&flag);
  if(timeout == 0)
	{
		data_reg = pssi->DR; 
	  DRV_SSI_GetFlag(pssi,SSI_FLAG_INDEX_RFNE,&flag);
		if(flag == SET)
		{
		    return DRV_SSI_ERROR;
		}
	}
	else
	while(flag == SET)
	{
		timeout --;
		data_reg = pssi->DR;                                    //清空fifo		
		if(timeout == 0)
		{
			return DRV_SSI_TIMEOUT;
		}
		DRV_SSI_GetFlag(pssi,SSI_FLAG_INDEX_RFNE,&flag); 
	}	
  *status = data_reg&0xff;	
  return DRV_SSI_OK;
}

/**
 *@brief 初始化SSI模块的设置.
 *
 *@param[in] pssi    指向SSI_TypeDef结构体的指针;
 *@param[in] pinit   指向SSI_InitTypeDef结构体的指针;
 *@param[in] timeout 超时时间;
 *@return DRV_SSI_StatusTypeDef @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef DRV_SSI_Init(SSI_TypeDef *pssi, SSI_InitTypeDef *pinit,uint32_t timeout)
{ 
    DRV_SSI_StatusTypeDef tmp_flag = DRV_SSI_ERROR;
		FlagStatusTypeDef flag = RESET;
		uint8_t status;
	  
	 if((pinit->Format == DUAL_mode) ||(pinit->Format == QUAD_mode))
		{
			DRV_SSI_CS_DisInit(pssi);
		}
   	
    tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
    if(tmp_flag != DRV_SSI_OK)
    {
        return tmp_flag;
    }
		DRV_SSI_Cmd(pssi,DISABLE);
		pssi->CTRLR0 = (pinit->DFS<<0)|(pinit->FRF<<6)|(pinit->SCPH<<8)|(pinit->SCPOL<<9)|(pinit->TMOD<<10)|(pinit->SRL<<13)|(pinit->SSTE<<14)|(pinit->CFS<<16)|(pinit->Format<<22);     
  	pssi->CTRLR1 = pinit->NDF;
		//pssi->BAUDR  = pinit->SSI_BaudRatePrescaler;
		if(pinit->Format == STD_mode)
		{
		   pssi->BAUDR  = pinit->SSI_STD_BaudRatePrescaler;
		}
		if(pinit->Format == DUAL_mode)
		{
		   pssi->BAUDR  = pinit->SSI_DUAL_BaudRatePrescaler;
		}
		if(pinit->Format == QUAD_mode)
		{
		   pssi->BAUDR  = pinit->SSI_QUAD_BaudRatePrescaler;
		}
		pssi->TXFTLR = (pinit->Transfer_start_FIFO_level<<16)|(pinit->Transmit_FIFO_Threshold);
		pssi->RXFTLR = pinit->Receive_FIFO_Threshold;
		pssi->IMR    = 0;
		pssi->SPICTRLR0 = (pinit->Trans_Type<<0)|(pinit->Address_Length<<2)|(pinit->Instruction_length<<8)|(pinit->WAIT_CYCLES<<11)|(pinit->CLK_STRETCH_EN<<30);
   
		pssi ->RXSDR = pinit->Rx_Sample_Delay;
		
		DRV_SSI_Cmd(pssi,ENABLE);  
		
		if(pinit->Format == STD_mode)
		{
			DRV_SSI_CS_Init(pssi);
		}
		
    return(DRV_SSI_OK);
}
/**
  *@brief SSI STD 初始化
  *
  *@param[in]  pssi        指向SSI_TypeDef的指针;
  *@param[in]  read        读写标志;
  *@param[in]  num         数据帧;
  *@param[in]  waitCycles  等待时间;
  *@param[in]  timeout     超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_STD_Init(SSI_TypeDef *pssi,uint32_t baund,uint32_t timeout)
{
	DRV_SSI_StatusTypeDef tmp_flag;
	SSI_InitTypeDef ssi_ini;
	
	DRV_SSI_StructInit(&ssi_ini);
	ssi_ini.DFS    = DFS_08_BIT;
	ssi_ini.Format = STD_mode;
	ssi_ini.SSI_STD_BaudRatePrescaler = baund;

	DRV_SSI_Cmd(pssi,DISABLE);
	tmp_flag = DRV_SSI_Init(pssi,&ssi_ini,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}
	DRV_SSI_Cmd(pssi,ENABLE);   
	
	return DRV_SSI_OK;
}

/**
  *@brief SSI DUAL 初始化
  *
  *@param[in]  pssi        指向SSI_TypeDef的指针;
  *@param[in]  data_len    需要读的数据长度;
  *@param[in]  waitCycles  等待时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_DUAL_Init(SSI_TypeDef *pssi,uint16_t baund,DRV_SSI_ReadTypeDef read,uint32_t data_len, uint32_t waitCycles,uint32_t timeout)
{
	DRV_SSI_StatusTypeDef tmp_flag;
	SSI_InitTypeDef ssi_ini;
	
	DRV_SSI_Cmd(pssi,DISABLE);
	DRV_SSI_StructInit(&ssi_ini);
  ssi_ini.SSI_DUAL_BaudRatePrescaler = baund;
  ssi_ini.NDF = data_len;
	ssi_ini.DFS = DFS_08_BIT;
	ssi_ini.Format = DUAL_mode;
	ssi_ini.FRF = FRF_SPI;
	if(read == DRV_SSI_READ)
	{
	   ssi_ini.TMOD = RX_ONLY;
		 ssi_ini.Transfer_start_FIFO_level = 0x01;
		 ssi_ini.Transmit_FIFO_Threshold = 0;
		 ssi_ini.Receive_FIFO_Threshold = 0x07; 
	}
	else
	{
	   ssi_ini.TMOD = TX_ONLY;
		 ssi_ini.Transfer_start_FIFO_level = 0;
		 ssi_ini.Transmit_FIFO_Threshold = 0;
		 ssi_ini.Receive_FIFO_Threshold = 0; 
	}
	ssi_ini.Trans_Type = TT0;
	ssi_ini.Address_Length = ADDR_L24;
	ssi_ini.Instruction_length = INST_L8;
	ssi_ini.WAIT_CYCLES = waitCycles;
	ssi_ini.CLK_STRETCH_EN = CLK_STRETCH_ENABLE; 
	
	pssi->IMR = 0x00;
//	if(ssi_ini.SSI_BaudRatePrescaler==0x02)//high speed  ////	if(QUAD_BAUDR==0x02&&g_sys_clk>=80000000)//high speed
//	{
//	   pssi->RXSDR=0x00010001;
//	}
	tmp_flag = DRV_SSI_Init(pssi,&ssi_ini,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}
	DRV_SSI_Cmd(pssi,ENABLE);   	

	return DRV_SSI_OK;
}

/**
  *@brief SSI QUAD 初始化
  *
  *@param[in]  pssi        指向SSI_TypeDef的指针;
  *@param[in]  read        读写标志;
  *@param[in]  num         数据帧;
  *@param[in]  waitCycles  等待时间;
  *@param[in]  timeout     超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_QUAD_Init(SSI_TypeDef *pssi,uint16_t baund,DRV_SSI_ReadTypeDef read,uint32_t num,uint32_t waitCycles,uint32_t timeout)
{
	DRV_SSI_StatusTypeDef tmp_flag;
	SSI_InitTypeDef ssi_ini;
	
	DRV_SSI_Cmd(pssi,DISABLE);
	DRV_SSI_StructInit(&ssi_ini);
	ssi_ini.DFS    = DFS_08_BIT;
	ssi_ini.Format = QUAD_mode;
	ssi_ini.NDF    = num;
	ssi_ini.SSI_QUAD_BaudRatePrescaler = baund;

	
	 if(read)
	 {
		  ssi_ini.TMOD = RX_ONLY;
	 }
   else
   {		 
	    ssi_ini.TMOD = TX_ONLY;
	 }	 
	 if(read)
	 {
		 ssi_ini.Transfer_start_FIFO_level = 0x01;
		 ssi_ini.Transmit_FIFO_Threshold = 0;
		 ssi_ini.Receive_FIFO_Threshold = 0x07; 
	 }
   else
   {	
		 ssi_ini.Transfer_start_FIFO_level = 2;
		 ssi_ini.Transmit_FIFO_Threshold = 0;
		 ssi_ini.Receive_FIFO_Threshold = 0; 
	 }	 
	ssi_ini.Address_Length = ADDR_L24;
	ssi_ini.Instruction_length = INST_L8;
	ssi_ini.WAIT_CYCLES = waitCycles;
	ssi_ini.CLK_STRETCH_EN = CLK_STRETCH_ENABLE;
	 
  	pssi->IMR = 0x00;
	 
	tmp_flag = DRV_SSI_Init(pssi,&ssi_ini,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}
	DRV_SSI_Cmd(pssi,ENABLE);   	
	
	return DRV_SSI_OK;
}

/**
 *@brief SSI QUAD初始化(以byte为传输单位)
 *
 *@param[in] pssi        指向SSI_TypeDef结构体的指针;
 *@param[in] mode        QPI执行模式;
 *@param[in] data_len    数据帧(写最大配置为256 byte,读最大配置为64k byte);
 *@param[in] waitCycles  等待时间;
 *@return DRV_SSI_StatusTypeDef @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef DRV_SSI_QPI_Init(SSI_TypeDef *pssi,uint16_t baund,QPI_OPT_MODE mode, uint32_t data_len, uint8_t waitCycles,uint32_t timeout)
{
	DRV_SSI_StatusTypeDef tmp_flag;
	SSI_InitTypeDef ssi_ini;
	
	DRV_SSI_Cmd(pssi,DISABLE);
	DRV_SSI_StructInit(&ssi_ini);	
	
	ssi_ini.SSI_QUAD_BaudRatePrescaler = baund;	 
	ssi_ini.NDF    = data_len;
	ssi_ini.DFS    = DFS_08_BIT;
	
	if(mode == CMD_READ)
	{
		ssi_ini.Format = QUAD_mode;
		ssi_ini.FRF = FRF_SPI;
		ssi_ini.TMOD  = RX_ONLY;

		ssi_ini.Trans_Type = TT2;
		ssi_ini.Address_Length = ADDR_L0;
		ssi_ini.Instruction_length = INST_L8;
		ssi_ini.WAIT_CYCLES = waitCycles;
		ssi_ini.CLK_STRETCH_EN = CLK_STRETCH_ENABLE;
		
		ssi_ini.Transfer_start_FIFO_level = 0x0001;
		ssi_ini.Transmit_FIFO_Threshold = 0;
		ssi_ini.Receive_FIFO_Threshold = 0x07; 
	}
	else if(mode == CMD_WRITE)
	{
		ssi_ini.Format = QUAD_mode;
		ssi_ini.FRF = FRF_SPI;
		ssi_ini.TMOD  = TX_ONLY;

		ssi_ini.Trans_Type = TT2;
		ssi_ini.Address_Length = ADDR_L0;
		ssi_ini.Instruction_length = INST_L8;
		ssi_ini.WAIT_CYCLES = waitCycles;
		ssi_ini.CLK_STRETCH_EN = CLK_STRETCH_ENABLE;
		
		if(data_len == 0)
		{
			ssi_ini.Transfer_start_FIFO_level = 0;
			ssi_ini.Transmit_FIFO_Threshold = 0;
		}
		else
		{
			ssi_ini.Transfer_start_FIFO_level = 0x0001;
			ssi_ini.Transmit_FIFO_Threshold = 0;
		}
		ssi_ini.Receive_FIFO_Threshold = 0;
	}
	else if(mode == DATA_READ)
	{
		ssi_ini.Format = QUAD_mode;
		ssi_ini.FRF = FRF_SPI;
		ssi_ini.TMOD  = RX_ONLY;

		ssi_ini.Trans_Type = TT2;
		ssi_ini.Address_Length = ADDR_L24;
		ssi_ini.Instruction_length = INST_L8;
		ssi_ini.WAIT_CYCLES = waitCycles;
		ssi_ini.CLK_STRETCH_EN = CLK_STRETCH_ENABLE;
		
		ssi_ini.Transfer_start_FIFO_level = 0x0001;
		ssi_ini.Transmit_FIFO_Threshold = 0;
		ssi_ini.Receive_FIFO_Threshold = 0x07; 	

	}
	else //DATA_WRITE
	{
		ssi_ini.Format = QUAD_mode;
		ssi_ini.FRF = FRF_SPI;
		ssi_ini.TMOD  = TX_ONLY;

		ssi_ini.Trans_Type = TT2;
		ssi_ini.Address_Length = ADDR_L24;
		ssi_ini.Instruction_length = INST_L8;
		ssi_ini.WAIT_CYCLES = waitCycles;
		ssi_ini.CLK_STRETCH_EN = CLK_STRETCH_ENABLE;

		ssi_ini.Transfer_start_FIFO_level = 0x0002;
		ssi_ini.Transmit_FIFO_Threshold = 0;
		ssi_ini.Receive_FIFO_Threshold = 0x02; 	

		
		pssi->DMATDLR = 0x02;	
	}

	pssi->IMR = 0x00;
	
	tmp_flag = DRV_SSI_Init(pssi,&ssi_ini,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}
	DRV_SSI_Cmd(pssi,ENABLE);  
	
	return DRV_SSI_OK;
}
/**
 *@brief 获取SSI Flash状态1
 *
 *@param[in] pssi        指向SSI_TypeDef结构体的指针;
 *@param[in] status      指向状态的指针;
 *@param[in] timeout     超时时间;
 *@return 结果 @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_Get_Status1(SSI_TypeDef *pssi,uint8_t *status,uint32_t timeout)
{ 
	FlagStatusTypeDef flag;
	DRV_SSI_StatusTypeDef state = DRV_SSI_ERROR;
	uint32_t TIMEOUT;
	volatile uint32_t data_reg;
 DRV_SSI_CS_LOW(pssi);
	pssi->DR = GET_SAT1_CMD;
	pssi->DR = DUMMY_BYTE;	
  __asm("nop");	__asm("nop");	 
	state = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(state != DRV_SSI_OK)
	{
		return state;
	}
	state = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(state != DRV_SSI_OK)
	{
		return state;
	}
	DRV_SSI_GetFlag(pssi,SSI_FLAG_INDEX_RFNE,&flag);
	if(flag != SET)
	{
			return DRV_SSI_ERROR;
	}
	TIMEOUT = timeout;
	do
	{
		data_reg = pssi->DR;
		DRV_SSI_GetFlag(pssi,SSI_FLAG_INDEX_RFNE,&flag);
		TIMEOUT --;
		if(TIMEOUT == 0)
		{
		    return DRV_SSI_TIMEOUT;
		}
	}
	while(flag == SET);
  *status = data_reg&0xff;
	
	DRV_SSI_CS_HIGH(pssi);
	return DRV_SSI_OK;
}	
/**
 *@brief 获取SSI Flash 状态2
 *
 *@param[in] pssi        指向SSI_TypeDef结构体的指针;
 *@param[in] status      指向状态的指针;
 *@param[in] timeout     超时时间;
 *@return 结果 @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_Get_Status2(SSI_TypeDef *pssi,uint8_t *status,uint32_t timeout)
{ 
	FlagStatusTypeDef flag;
	DRV_SSI_StatusTypeDef state = DRV_SSI_ERROR;
	uint32_t TIMEOUT;
	volatile uint32_t data_reg;
	
	DRV_SSI_CS_LOW(pssi);
	pssi->DR = GET_SAT2_CMD;
	pssi->DR = DUMMY_BYTE;	
	 __asm("nop");	__asm("nop");	
	state = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(state != DRV_SSI_OK)
	{
		return state;
	}
	state = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(state != DRV_SSI_OK)
	{
		return state;
	}
	DRV_SSI_GetFlag(pssi,SSI_FLAG_INDEX_RFNE,&flag);
	if(flag != SET)
	{
			return DRV_SSI_ERROR;
	}
	TIMEOUT = timeout;
	do
	{
		data_reg = pssi->DR;
		DRV_SSI_GetFlag(pssi,SSI_FLAG_INDEX_RFNE,&flag);
		TIMEOUT --;
		if(TIMEOUT == 0)
		{
		    return DRV_SSI_TIMEOUT;
		}
	}
	while(flag == SET);
  *status = data_reg&0xff;
  DRV_SSI_CS_HIGH(pssi);	
	return DRV_SSI_OK;
}
/**
 *@brief 等待SSI Flash状态1
 *
 *@param[in] pssi        指向SSI_TypeDef结构体的指针;
 *@param[in] val         状态1期望值;
 *@param[in] timeout     超时时间;
 *@return 结果 @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_WAIT_Status1(SSI_TypeDef *pssi,uint8_t val,uint32_t timeout)
{ 
	DRV_SSI_StatusTypeDef state = DRV_SSI_ERROR;
	uint8_t status = 0xff;
	uint32_t TIMEOUT = timeout;
	do
	{	
		state = DRV_SSI_EFlash_Get_Status1(pssi,&status,timeout);
		if(state != DRV_SSI_OK)
		{
				return state;
		}		
    TIMEOUT --;
    if(TIMEOUT == 0)
		{
		    return DRV_SSI_TIMEOUT;
		}			
	}while(status&val);	

	
	return DRV_SSI_OK;
}	
/**
 *@brief SSI QUAD 初始化 (以byte为传输单位，Burst传输,传输长度需要是4的倍数）
 *
 *@param[in] pssi        指向SSI_TypeDef结构体的指针;
 *@param[in] read        读写标志 1:read  0:write;
 *@param[in] num         数据帧(写最大配置为256 byte,读最大配置为64k byte);
 *@param[in] waitCycles  等待时间;
 *@param[in] timeout     超时时间;
 *@return 结果 @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef SSI_QUAD_Burst_Init(SSI_TypeDef *pssi,DRV_SSI_ReadTypeDef read,uint32_t num,uint32_t waitCycles,uint32_t timeout)
{
	DRV_SSI_StatusTypeDef tmp_flag;
   tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,RESET,timeout);
   if(tmp_flag != DRV_SSI_OK)
   {
       return tmp_flag;
   }
   pssi->SSIENR = 0x00;
	 pssi->CTRLR1 = num-1;
	 if(read)
	 {
	    pssi->CTRLR0 = 0x00800807;
	 }
   else
   {		 
	    pssi->CTRLR0 = 0x00800407;
	 }	 
	 pssi->BAUDR =  QUAD_BAUDR;
	 if(read)
	 {
	    pssi->TXFTLR = 0x00010000;
	    pssi->RXFTLR = 0x07;	 
		  pssi->DMARDLR= 0x03;		
	 }
   else
   {		 
	    pssi->TXFTLR = 0x00020000;
	    pssi->RXFTLR = 0x00;
	 }	 
//	 if(QUAD_BAUDR==0x02&&g_sys_clk>=80000000)//high speed
	 if(QUAD_BAUDR==0x02)
	 {
		 pssi->RXSDR=0x00010000;
	 }
   pssi->SPICTRLR0 = 0x40000218|(waitCycles<<11);
	 pssi->IMR = 0x00;
	 pssi->SSIENR = 0x01;
	 
	 return DRV_SSI_OK;
}

/**
 *@brief 获取SSI Flash状态1(QPI模式)
 *
 *@param[in] pssi        指向SSI_TypeDef结构体的指针;
 *@param[in] status      指向状态的指针;
 *@param[in] timeout     超时时间;
 *@return 结果 @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QPI_Get_Status1(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint8_t *status,uint32_t timeout)
{ 
	FlagStatusTypeDef flag;
	DRV_SSI_StatusTypeDef state = DRV_SSI_ERROR;
	uint32_t TIMEOUT;
	state = DRV_SSI_QPI_Init(pssi,pinit->SSI_QUAD_BaudRatePrescaler,CMD_READ,0,2,timeout);
	if(state != DRV_SSI_OK)
	{
		return state;
	}
	pssi->DR = GET_SAT1_CMD;		
	delay(3);
	state = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(state != DRV_SSI_OK)
	{
		return state;
	}
	state = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(state != DRV_SSI_OK)
	{
		return state;
	}
	TIMEOUT = timeout;
	do
	{
		*status = pssi->DR&0xff;
		DRV_SSI_GetFlag(pssi,SSI_FLAG_INDEX_RFNE,&flag);
		TIMEOUT --;
		if(TIMEOUT == 0)
		{
			return DRV_SSI_TIMEOUT;
		}
	}
	while(flag == SET);

	return (DRV_SSI_OK);
}	
/**
 *@brief 等待SSI Flash状态1(QPI)
 *
 *@param[in] pssi        指向SSI_TypeDef结构体的指针;
 *@param[in] val         状态1期望值;
 *@param[in] timeout     超时时间;
 *@return 结果 @ref DRV_SSI_StatusTypeDef
 */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QPI_WAIT_Status1(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint8_t val,uint32_t timeout)
{ 
	DRV_SSI_StatusTypeDef state = DRV_SSI_ERROR;
	uint8_t status ;
	uint32_t TIMEOUT = timeout;
	do
	{	
		state = DRV_SSI_EFlash_QPI_Get_Status1(pssi,pinit,&status,timeout);
		if(state != DRV_SSI_OK)
		{
				return state;
		}		
    TIMEOUT --;
    if(TIMEOUT == 0)
		{
		    return DRV_SSI_TIMEOUT;
		}			
	}while(status&val);	

	
	return DRV_SSI_OK;
}	

/**
  *@brief SSI FLASH写使能
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_Write_Enable(SSI_TypeDef *pssi,uint32_t timeout)
{
	FlagStatusTypeDef flag;
	DRV_SSI_StatusTypeDef tmp_flag;
	uint8_t status;
	
	tmp_flag = DRV_SSI_EFlash_Get_Status1(pssi,&status,timeout);
  if(tmp_flag != DRV_SSI_OK)
  {
      return tmp_flag;
  }		
	if((status&0x02) == 0)
	{
		DRV_SSI_CS_LOW(pssi);
		pssi->DR = WRITE_EN_CMD;	
		delay(3);		
		tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
		if(tmp_flag != DRV_SSI_OK)
		{
				return tmp_flag;
		}	
		tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
		if(tmp_flag != DRV_SSI_OK)
		{
				return tmp_flag;
		}	
		tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	  if(tmp_flag != DRV_SSI_OK)
	  {
			return tmp_flag;
	  }
    DRV_SSI_CS_HIGH(pssi);		
		tmp_flag = DRV_SSI_EFlash_WAIT_Status1(pssi,0x01,timeout);
		if(tmp_flag != DRV_SSI_OK)
		{
				return tmp_flag;
		}	
	}
	return DRV_SSI_OK;
}	
/**
  *@brief SSI FLASH reset 使能.
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_STD_Reset_Enable(SSI_TypeDef *pssi,uint32_t timeout)
{
	uint8_t status;
	DRV_SSI_StatusTypeDef tmp_flag;
	
	DRV_SSI_CS_LOW(pssi);
	pssi->DR = Reset_EN_CMD;	
	delay(3);		
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);

	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	DRV_SSI_CS_HIGH(pssi);
	return DRV_SSI_OK;
}	
/**
  *@brief SSI FLASH reset.
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_STD_Reset(SSI_TypeDef *pssi,uint32_t timeout)
{
	uint8_t status;
	DRV_SSI_StatusTypeDef tmp_flag;
	DRV_SSI_CS_LOW(pssi);
	pssi->DR = Reset_CMD;	
	delay(3);		
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	DRV_SSI_CS_HIGH(pssi);
	return DRV_SSI_OK;
}	

/**
  *@brief 获取Device ID.
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  *ID ID指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_STD_Read_ID(SSI_TypeDef *pssi,uint16_t *ID,uint32_t timeout)
{
	DRV_SSI_StatusTypeDef tmp_flag;
	uint32_t i;
	
  tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
  if(tmp_flag != DRV_SSI_OK)
  {
      return tmp_flag;
  }
	
	DRV_SSI_CS_LOW(pssi);
	pssi->DR = READ_ID_CMD;
	pssi->DR = 0x00;
	pssi->DR = 0x00;
	pssi->DR = 0x00;

	pssi->DR = DUMMY_BYTE;
	pssi->DR = DUMMY_BYTE;	
	__asm("nop");	__asm("nop"); 
  tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
  if(tmp_flag != DRV_SSI_OK)
  {
      return tmp_flag;
  }	
  tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
  if(tmp_flag != DRV_SSI_OK)
  {
      return tmp_flag;
  }	
	for(i=0; i<4; i++)
	{
		*ID = pssi->DR;
	}
	*ID = pssi->DR;
	*ID|= pssi->DR << 8;
	DRV_SSI_CS_HIGH(pssi);
	return DRV_SSI_OK;
}	
/**
  *@brief 读SSI Flash 数据(STD)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 读取的地址;
  *@param[in]  num  读取的长度;
  *@param[in]  buf  读取的数据指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_STD_Read(SSI_TypeDef *pssi,uint32_t addr,uint32_t num,uint8_t *buf,uint32_t timeout)
{   
	uint8_t temp;
	uint32_t i=0,j=0,TIMEOUT;
	uint32_t txnum;
	DRV_SSI_StatusTypeDef tmp_flag;
	FlagStatusTypeDef flag;
	
	txnum = num;
	DRV_SSI_CS_LOW(pssi);
	pssi->DR = READ_CMD;
	pssi->DR = (addr>>16)&0xff;
	pssi->DR = (addr>>8)&0xff;
	pssi->DR = (addr>>0)&0xff;
	delay(3);
	TIMEOUT = timeout;
	while(num>0)
	{
		if((pssi->SR&SR_TFNF)&&(txnum>0))
		{
			pssi->DR=DUMMY_BYTE;
			txnum--;
		}
		if(pssi->SR&SR_RFNE)
		{
			if(j < 4)
			{
				temp=pssi->DR;
				j++;
			}
			else
			{
				*(buf+i)=pssi->DR;
				 i++;
				 num--;
				 TIMEOUT = timeout;
			}
		}
		else
		{
		    TIMEOUT --;
			  if(TIMEOUT == 0)
				{
						return DRV_SSI_TIMEOUT;
				}
		}
	}
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	DRV_SSI_CS_HIGH(pssi);
	return DRV_SSI_OK;	
}
/**
  *@brief SSI Flash 写数据
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 写入的地址;
  *@param[in]  num  写入的长度;
  *@param[in]  buf  写入的数据指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_STD_Program(SSI_TypeDef *pssi,uint32_t addr,uint32_t num,uint8_t *buf,uint32_t timeout)
{
	uint8_t temp;
	uint8_t status;
	DRV_SSI_StatusTypeDef tmp_flag;
	
	tmp_flag = DRV_SSI_EFlash_Write_Enable(pssi,timeout);	
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	DRV_SSI_CS_LOW(pssi);
	pssi->DR = PAGE_PROG_CMD;
	pssi->DR = (addr>>16)&0xff;
	pssi->DR = (addr>>8)&0xff;
	pssi->DR = (addr>>0)&0xff;
	 
#ifdef INTERRUPT_TEST
	 pssi->IMR=0x01;
#endif	 

	while(num>0)
	{	
		if(pssi->SR&SR_TFNF)
		{
			 pssi->DR = *buf;
			 buf++;
			 num--; 
		}	
		if(pssi->SR&SR_RFNE)
		{
			 temp=pssi->DR;
		}	
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}

  tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	 DRV_SSI_CS_HIGH(pssi);
	tmp_flag = DRV_SSI_EFlash_WAIT_Status1(pssi,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	return DRV_SSI_OK;
}	
/**
  *@brief 擦除1sector FLASH(4k)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 擦除的地址;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_STD_Sector_Erase(SSI_TypeDef *pssi,uint32_t addr,uint32_t timeout)
{
	DRV_SSI_StatusTypeDef tmp_flag;
	FlagStatusTypeDef flag;
	uint8_t status;
	
	DRV_SSI_STD_Init(pssi,0x4,timeout);
	
	tmp_flag = DRV_SSI_EFlash_Write_Enable(pssi,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
  DRV_SSI_CS_LOW(pssi);	
	pssi->DR = SECT_ERASE_CMD;
	pssi->DR = (addr>>16)&0xff;
	pssi->DR = (addr>>8)&0xff;
	pssi->DR = (addr>>0)&0xff;	
	__asm("nop");	__asm("nop");	 
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
  DRV_SSI_CS_HIGH(pssi);
	
	tmp_flag = DRV_SSI_EFlash_WAIT_Status1(pssi,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	return DRV_SSI_OK;	
}

/**
  *@brief 擦除1Block FLASH(64k)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 擦除的地址;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_STD_Block_Erase(SSI_TypeDef *pssi,uint32_t addr,uint32_t timeout)
{
	DRV_SSI_StatusTypeDef tmp_flag;
	FlagStatusTypeDef flag;
	uint8_t status;
	
	tmp_flag = DRV_SSI_EFlash_Write_Enable(pssi,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
  DRV_SSI_CS_LOW(pssi);	
	pssi->DR = W25X_BlockErase;
	pssi->DR = (addr>>16)&0xff;
	pssi->DR = (addr>>8)&0xff;
	pssi->DR = (addr>>0)&0xff;	
	__asm("nop");	__asm("nop");	 
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
  DRV_SSI_CS_HIGH(pssi);
	
	tmp_flag = DRV_SSI_EFlash_WAIT_Status1(pssi,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	return DRV_SSI_OK;	
}

/**
  *@brief 读SSI Flash 数据(QUAD)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 读取的地址;
  *@param[in]  num  读取的长度;
  *@param[in]  buf  读取的数据指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QUAD_Read(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint32_t addr,uint32_t num,uint8_t *buf,uint32_t timeout)
{
	uint8_t temp;
	uint8_t status;
	uint32_t i=0;
	DRV_SSI_StatusTypeDef tmp_flag;

	tmp_flag = DRV_SSI_QUAD_Init(pssi,pinit->SSI_QUAD_BaudRatePrescaler,1, num-1,8,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	pssi->DR = QUAD_READ_CMD;
	pssi->DR = addr;
	__asm("nop");__asm("nop");__asm("nop");
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	

	while(((num>0)&&(pssi->SR&SR_BUSY))||(pssi->SR&SR_RFNE))
	{
		if(pssi->SR&SR_RFNE)
		{
				*(buf+i)=pssi->DR;
				i++;
				num--;
		}	
	}
	
	return DRV_SSI_OK;
}



/**
  *@brief SSI Flash 写数据(QUAD)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 写入的地址;
  *@param[in]  num  写入的长度;
  *@param[in]  buf  写入的数据指针;
  *@param[in] timeout 超时时间;
  *@return 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QUAD_Program(SSI_TypeDef *pssi, SSI_InitTypeDef *pinit,uint32_t addr,uint32_t num,uint8_t *buf,uint32_t timeout)
{
	uint8_t temp;
	uint8_t status;
	DRV_SSI_StatusTypeDef tmp_flag;
	tmp_flag = DRV_SSI_STD_Init(pssi,pinit->SSI_STD_BaudRatePrescaler,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		
	tmp_flag = DRV_SSI_EFlash_Write_Enable(pssi,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		
	tmp_flag = DRV_SSI_QUAD_Init(pssi,pinit->SSI_QUAD_BaudRatePrescaler,0,num-1,8,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	pssi->DR=QUAD_PROG_CMD;
	pssi->DR=addr;

	while(num>0)
	{	
	 if(pssi->SR&SR_TFNF)
	 {
		 pssi->DR=*buf;
		 buf++;
		 num--; 
	 }	
	 if(pssi->SR&SR_RFNE)
	 {
		 temp=pssi->DR;
	 }	
	}	
  tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}
	tmp_flag = DRV_SSI_STD_Init(pssi,pinit->SSI_STD_BaudRatePrescaler,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}	
	tmp_flag = DRV_SSI_EFlash_WAIT_Status1(pssi,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	DRV_SSI_QUAD_Init(pssi,pinit->SSI_QUAD_BaudRatePrescaler,0,num-1,8,timeout);
	return DRV_SSI_OK;
}

/**
  *@brief 读SSI Flash 数据(QPI)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 读取的地址;
  *@param[in]  num  读取的长度;
  *@param[in]  buf  读取的数据指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QPI_Read(SSI_TypeDef *pssi,uint32_t addr,uint32_t num,uint8_t *buf,uint32_t timeout)
{
	uint32_t i=0;
	DRV_SSI_StatusTypeDef tmp_flag;
	uint32_t TIMOEOUT;
	tmp_flag = DRV_SSI_QPI_Init(pssi,DRV_Get_SSI_baund(pssi),DATA_READ,num-1,8,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		

	pssi->DR = QPI_READ_CMD;
	pssi->DR = addr;
	
	//delay(3);
  __asm("nop");	__asm("nop");
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	TIMOEOUT = timeout;
	while(num>0)
	{
		if(pssi->SR&SR_RFNE)
		{ 
			*(buf+i)=pssi->DR;
			i++;
			num--;
		}
		else
		{
			TIMOEOUT --;
		}
		if(TIMOEOUT == 0)
		{
		    return DRV_SSI_TIMEOUT;
		}
	}
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}
  return DRV_SSI_OK;	
}	

/**
  *@brief SSI FLASH写使能(QPI)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QPI_Write_Enable(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint32_t timeout)
{
	uint8_t  status;
	uint8_t temp;
	DRV_SSI_StatusTypeDef tmp_flag;
	
	tmp_flag = DRV_SSI_EFlash_QPI_Get_Status1(pssi,pinit,&status,timeout);
  if(tmp_flag != DRV_SSI_OK)
  {
      return tmp_flag;
  }	
	if((status&0x02) == 0)
	{
		tmp_flag = DRV_SSI_QPI_Init(pssi,pinit->SSI_QUAD_BaudRatePrescaler,CMD_WRITE,0,2,timeout);
		if(tmp_flag != DRV_SSI_OK)
		{
				return tmp_flag;
		}			
		pssi->DR = WRITE_EN_CMD;
	
		delay(3);
			
		tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
		if(tmp_flag != DRV_SSI_OK)
		{
				return tmp_flag;
		}
		do
		{
			tmp_flag = DRV_SSI_EFlash_QPI_Get_Status1(pssi,pinit,&status,timeout);
			if(tmp_flag != DRV_SSI_OK)
			{
					return tmp_flag;
			}			 
		}while(status&0x01);		
	}
	return DRV_SSI_OK;	
}	

/**
  *@brief SSI EFlash 进入QPI模式
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QPI_Enter(SSI_TypeDef *pssi,uint32_t timeout)
{
	uint8_t status;
	DRV_SSI_StatusTypeDef tmp_flag;
	FlagStatusTypeDef flag;
	uint32_t TIMEOUT;
	
	DRV_SSI_CS_LOW(pssi);
	pssi->DR = QPI_ENTER_CMD;
	__asm("nop");	__asm("nop");

	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		
	tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	DRV_SSI_CS_HIGH(pssi);
	return DRV_SSI_OK;		
}

/**
  *@brief SSI EFlash 退出QPI模式
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QPI_EXIT(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint32_t timeout)
{
	uint8_t status;
	DRV_SSI_StatusTypeDef tmp_flag;
	SSI_InitTypeDef ssi_ini;
	
	tmp_flag = DRV_SSI_QPI_Init(pssi,pinit->SSI_QUAD_BaudRatePrescaler,CMD_WRITE,0,2,timeout);	
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	pssi->DR = QPI_EXIT_CMD;
	delay(3);	
	tmp_flag = DRV_SSI_STD_Init(pssi,pinit->SSI_STD_BaudRatePrescaler,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		
	tmp_flag = DRV_SSI_EFlash_WAIT_Status1(pssi,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	return DRV_SSI_OK;
}
/**
  *@brief 设置SSI Flash状态1与状态2 
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  val1 Flash状态1;
  *@param[in]  val2 Flash状态2;
  *@param[in]  timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_Prog_Status12(SSI_TypeDef *pssi,uint8_t val1,uint8_t val2,uint32_t timeout)
{
	uint8_t status;
	uint8_t retVal;
	DRV_SSI_StatusTypeDef tmp_flag;
	FlagStatusTypeDef flag;
//	tmp_flag = DRV_SSI_EFlash_Write_Enable(pssi,timeout);
//	if(tmp_flag != DRV_SSI_OK)
//	{
//			return tmp_flag;
//	}
	pssi->DR=PROG_STA12_CMD;
	pssi->DR=val1;
  pssi->DR=val2;
	__asm("nop");	__asm("nop");
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_RFNE,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		

	tmp_flag = DRV_SSI_EFlash_WAIT_Status1(pssi,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	return DRV_SSI_OK;
}	
/**
  *@brief 设置SSI Flash状态2 
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  val Flash状态2;
  *@param[in]  timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_Prog_Status2(SSI_TypeDef *pssi,uint8_t val,uint32_t timeout)
{
	uint8_t status;
	uint8_t retVal;
	DRV_SSI_StatusTypeDef tmp_flag;
	FlagStatusTypeDef flag;
  DRV_SSI_CS_LOW(pssi);
	pssi->DR = PROG_STA2_CMD;
	pssi->DR = val;

	__asm("nop");	__asm("nop");
	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		
	tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	DRV_SSI_CS_HIGH(pssi);
	tmp_flag = DRV_SSI_EFlash_WAIT_Status1(pssi,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	return DRV_SSI_OK;
}	

/**
  *@brief SSI EFlash 设置读参数
  *
  *@param[in] pssi    指向SSI_TypeDef结构体的指针;
  *@param[in] pinit   指向SSI_InitTypeDef结构体的指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_EFlash_Set_Read_Para(SSI_TypeDef *pssi,uint16_t baund,uint8_t para,uint32_t timeout)
{
  DRV_SSI_StatusTypeDef tmp_flag;
	uint8_t status;
	SSI_InitTypeDef ssi_ini;
	DRV_SSI_CS_DisInit(pssi);
	
  pssi->SSIENR = 0x00;
	pssi->CTRLR1 = 0x00;
  pssi->CTRLR0 = 0x00800407;
	pssi->SPICTRLR0 = 0x40000202|(6<<11);
	//pssi->BAUDR =  0x10;
	pssi->BAUDR =  baund;
	pssi->IMR = 0x00;
	pssi->SSIENR = 0x01;
	 
	pssi->DR = SET_READ_PARA_CMD;
	pssi->DR = para;
	delay(3);
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
  tmp_flag = DRV_SSI_clear_fifo(pssi,&status,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	

	return DRV_SSI_OK;
}	
/**
  *@brief 读SSI Flash 数据(DUAL)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 读取的地址;
  *@param[in]  num  读取的长度;
  *@param[in]  buf  读取的数据指针;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_DUAL_Read(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint32_t addr, uint32_t num,uint8_t *buf,uint32_t timeout)
{  

	uint8_t temp;
	uint32_t i=0;
	DRV_SSI_StatusTypeDef tmp_flag;

	tmp_flag = DRV_SSI_DUAL_Init(pssi,pinit->SSI_DUAL_BaudRatePrescaler,DRV_SSI_READ,num-1,8,timeout);
	
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	pssi->DR = DUAL_READ_CMD;
	pssi->DR = addr;
	delay(3);
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	while(((num>0)&&(pssi->SR&SR_BUSY))||(pssi->SR&SR_RFNE))
	{
		if(pssi->SR&SR_RFNE)
		{
				*(buf+i)=pssi->DR;
				i++;
				num--;
		}	
	}
	
	return DRV_SSI_OK;
}	
/**
  *@brief 擦除1sector FLASH(4k) QPI
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 擦除的地址;
  *@param[in] timeout 超时时间;
  *@retval 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QPI_Sector_Erase(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint32_t addr,uint32_t timeout)
{
	volatile unsigned char status;
	unsigned char temp;
	DRV_SSI_StatusTypeDef tmp_flag;
	temp = temp;
	
	tmp_flag = DRV_SSI_EFlash_QPI_Write_Enable(pssi,pinit,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		
	tmp_flag = DRV_SSI_QPI_Init(pssi,DRV_Get_SSI_baund(pssi),CMD_WRITE,3-1,2,timeout);  
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	pssi->DR=SECT_ERASE_CMD;
	pssi->DR=(addr>>16)&0xFF;
	pssi->DR=(addr>>8)&0xFF;
	pssi->DR=addr&0xFF;
	delay(3);
	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_TFE,RESET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		

	tmp_flag = DRV_SSI_EFlash_QPI_WAIT_Status1(pssi,pinit,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		

	return DRV_SSI_OK;	 
}

/**
  *@brief SSI Flash 写数据(QPI)
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  addr 写入的地址;
  *@param[in]  num  写入的长度;
  *@param[in]  buf  写入的数据指针;
  *@param[in] timeout 超时时间;
  *@return 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_EFlash_QPI_Program(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint32_t addr,uint32_t num,uint8_t *buf,uint32_t timeout)
{
	uint8_t status;
	DRV_SSI_StatusTypeDef tmp_flag;
	tmp_flag = DRV_SSI_EFlash_QPI_Write_Enable(pssi,pinit,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	tmp_flag = DRV_SSI_QPI_Init(pssi,DRV_Get_SSI_baund(pssi),DATA_WRITE,num-1,2,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}		
	pssi->DR = PAGE_PROG_CMD;
	pssi->DR = addr;

	while(num>0)
	{	
		if(pssi->SR&SR_TFNF)
		{
		 pssi->DR=*buf;
		 buf++;
		 num--; 
		}	
	}
	tmp_flag = DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}
	tmp_flag = DRV_SSI_EFlash_QPI_WAIT_Status1(pssi,pinit,0x01,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
			return tmp_flag;
	}	
	
	return DRV_SSI_OK;
}
/**
  *@brief 使能SSI XIP
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  baund XIP速率;
  *@param[in]  sw  是否使能XIP;
  *@return 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_XIP_SET(SSI_TypeDef *pssi,uint32_t baund,uint8_t sw)
{
	if(sw == TRUE)
	{
		pssi->SSIENR = 0x00;
		pssi->XIPIIR = 0xeb;
		pssi->XIPWIR = 0x0c;	
		pssi->BAUDR = baund;
		pssi->XIPCR = 0x28c0046a|(6<<13);  	
		
		pssi->CTRLR0 = 0x0080001f;
		pssi->SPICTRLR0 = 0x6830021a|(4<<11);
		pssi->XIPMBR = 0x00000000;
		pssi->SSIENR= 0x01;
		
		delay(0x1000);
		if(pssi == SSI1)
		{
		 (*(uint32_t*)(0x40001000+0x3c))|=0x00000009;     //需要封库，不对客户开放
		}
		if(pssi == SSI2)
		{
			 (*(uint32_t*)(0x40001000+0x3c))|=0x00090000;  
		}
	}
	else
	{
			if(pssi == SSI1)
		{
	    
			(*(uint32_t*)(0x40001000+0x3c)) = ((*(uint32_t*)(0x40001000+0x3c)) &~ 0x00000009) | 0x00000008;	
		}
			if(pssi == SSI2)
		{
			(*(uint32_t*)(0x40001000+0x3c)) = ((*(uint32_t*)(0x40001000+0x3c)) &~ 0x00090000) | 0x00080000;	// 
		}
		delay(0x1000);
	}
	return DRV_SSI_OK;
}


/**
  *@brief 进入XIP模式
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  baund XIP速率;
  *@param[in]  timeout 超时时间;
  *@return 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_XIP_Enter(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit,uint32_t timeout)
{
	uint8_t temp1,temp2;
	DRV_SSI_StatusTypeDef tmp_flag;	
 
	tmp_flag = DRV_SSI_STD_Init(pssi,pinit->SSI_STD_BaudRatePrescaler,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}	
	tmp_flag = DRV_SSI_EFlash_Get_Status1(pssi,&temp1,timeout);	
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}
	tmp_flag = DRV_SSI_EFlash_Get_Status2(pssi,&temp2,timeout);	
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}
	if((temp2&0x02) != 0X02)
	{
		tmp_flag = DRV_SSI_EFlash_Write_Enable(pssi,timeout);
		if(tmp_flag != DRV_SSI_OK)
		{
			return tmp_flag;
		}
		delay(0x1000);
		//tmp_flag = DRV_SSI_EFlash_Prog_Status12(pssi,temp1,temp2|0x02,timeout);
		tmp_flag = DRV_SSI_EFlash_Prog_Status2(pssi,temp2|0x02,timeout);
		if(tmp_flag != DRV_SSI_OK)
		{
			return tmp_flag;
		}	
    if((temp2&0x02) == 0)
		{
			return DRV_SSI_ERROR;
		}
	}
	tmp_flag = DRV_SSI_EFlash_QPI_Enter(pssi,timeout); 
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}	
  tmp_flag = DRV_EFlash_Set_Read_Para(pssi,pinit->SSI_QUAD_BaudRatePrescaler,0x21,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}	
	tmp_flag = DRV_SSI_XIP_SET(pssi,pinit->SSI_QUAD_BaudRatePrescaler,TRUE);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}		
	return DRV_SSI_OK;
}	
/**
  *@brief 退出XIP模式
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  baund XIP速率;
  *@param[in]  timeout 超时时间;
  *@return 结果 @ref DRV_SSI_StatusTypeDef
  */
//DRV_SSI_StatusTypeDef DRV_XIP_EXIT(SSI_TypeDef *pssi,uint32_t baund,uint32_t timeout)
DRV_SSI_StatusTypeDef DRV_XIP_EXIT(SSI_TypeDef *pssi,SSI_InitTypeDef *pinit ,uint32_t timeout)
{
	uint8_t temp;
	DRV_SSI_StatusTypeDef tmp_flag;	
  
	tmp_flag = DRV_SSI_XIP_SET(pssi,pinit->SSI_STD_BaudRatePrescaler,FALSE);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}
	tmp_flag = DRV_SSI_EFlash_QPI_EXIT(pssi,pinit,timeout); 
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}	
  //tmp_flag = DRV_EFlash_Set_Read_Para(pssi,baund,0,timeout);
	//if(tmp_flag != DRV_SSI_OK)
	//{
	//	return tmp_flag;
	//}	
	tmp_flag = DRV_SSI_STD_Init(pssi,pinit->SSI_STD_BaudRatePrescaler,timeout);
	if(tmp_flag != DRV_SSI_OK)
	{
		return tmp_flag;
	}	
	return DRV_SSI_OK;
}
/**
  *@brief 启动SSI STD DMA
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  cmd 操作指令
  *@param[in]  addr 地址;
  *@param[in]  dmaConf 传输方式;
  *@return 无
  */
void DRV_SSI_STD_DMA_Trig(SSI_TypeDef *pssi, unsigned char cmd, unsigned int addr, int dmaConf)
{	
	pssi->DR=cmd;
	pssi->DR=(addr>>16)&0xff;
	pssi->DR=(addr>>8)&0xff;
	pssi->DR=(addr>>0)&0xff;

	pssi->DMACR=dmaConf;
}	
/**
  *@brief 启动SSI QUAD DMA
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  cmd 操作指令
  *@param[in]  addr 地址;
  *@param[in]  dmaConf 传输方式;
  *@return 无
  */
void DRV_SSI_DUAL_DMA_Trig(SSI_TypeDef *pssi, unsigned char cmd, unsigned int addr, int dmaConf)
{
	pssi->DR=cmd;
	pssi->DR=addr;

	pssi->DMACR=dmaConf;	 
}	
/**
  *@brief 启动SSI QUAD DMA 
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  cmd 操作指令
  *@param[in]  addr 地址;
  *@param[in]  dmaConf 传输方式;
  *@return 无
  */
void DRV_SSI_QUAD_DMA_Trig(SSI_TypeDef *pssi, unsigned char cmd, unsigned int addr, int dmaConf)
{
	pssi->DR=cmd;
	pssi->DR=addr;

	pssi->DMACR=dmaConf;	 
}	
/**
  *@brief 启动SSI QPI DMA 
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  cmd 操作指令
  *@param[in]  addr 地址;
  *@param[in]  dmaConf 传输方式;
  *@return 无
  */
void DRV_SSI_QPI_DMA_Trig(SSI_TypeDef *pssi, unsigned char cmd, unsigned int addr, int dmaConf)
{
	pssi->DR=cmd;
	pssi->DR=addr;

	pssi->DMACR=dmaConf;	 
}
/**
  *@brief DMA传输数据等级设置
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  level 等级
  *@return 无
  */
void DRV_SSI_DMA_Transmit_level(SSI_TypeDef *pssi,unsigned char level)
{
	pssi->DMATDLR=level;	 
}
/**
  *@brief DMA接收数据等级设置
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  level 等级
  *@return 无
  */
void DRV_SSI_DMA_Receive_level(SSI_TypeDef *pssi,unsigned char level)
{
	pssi->DMARDLR=level;	 
}
/**
  *@brief SSI wait IDLE
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@param[in]  timeout 超时时间;
  *@return 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef DRV_SSI_WAIT_IDLE(SSI_TypeDef *pssi,uint32_t timeout)
{
   return DRV_SSI_WaitonFlagTimeout(pssi,SSI_FLAG_INDEX_BUSY,SET,timeout);
}



DRV_SSI_StatusTypeDef __attribute__((used)) SysSsiConfigure(uint32_t ssi_id, uint32_t core_div, uint32_t sys_div, \
	                                        uint32_t ssi_baude, uint32_t sample_delay, uint32_t delayvalue)
{
	volatile uint32_t temp;
	volatile SSI_TypeDef *SSIReg;
	
 
	Disable_Interrupts;
	if(1 == ssi_id)
	{
	   
	  CCM->SSI_TRIM_CFG = (CCM->SSI_TRIM_CFG &~ 0x00000009) | 0x00000008;	// 
	  SSIReg = (SSI_TypeDef *)0x60000000;
	}
	else if(2 == ssi_id)
	{
  	 
	  CCM->SSI_TRIM_CFG = (CCM->SSI_TRIM_CFG &~ 0x00090000) | 0x00080000;	// 
	  SSIReg = (SSI_TypeDef *)0x70000000;
	}	
	else
	{
	  return DRV_SSI_ERROR;
	}
	
	
	
	temp=SSIReg->SR;	
 
	SSIReg->SSIENR = 0x00;
	CPM->SCDIVR = (CPM->SCDIVR &~ 0xf00000ff) |
					(((core_div - 1u) & 0xf) << 28) |
					(((sys_div - 1u) & 0xff) << 0);
	CPM->CDIVUPDR |= CPM_CDIVUPDR_SYS_DIV_UPDATE;
	 
	SSIReg->BAUDR = ssi_baude;
	SSIReg->RXSDR = sample_delay;
 
	SSIReg->SSIENR = 0x01;
 
	if(1 == ssi_id)
	{
	    CCM->SSI_TRIM_CFG |= 0x00000009;		
	}
	if(2 == ssi_id)
	{
	    CCM->SSI_TRIM_CFG |= 0x00090000;
	}
 
	Enable_Interrupts;
	 
	if(delayvalue > 0)
	{
	  while(delayvalue--);
	}
  return DRV_SSI_OK;
}

#define PSRAM_RNTERQUAD    0x35
#define PSRAM_CR           (*(volatile  unsigned int *)(0x40000078))

/**
  *@brief PSRAM初始化函数
  *
  *@param[in]  pssi 指向SSI_TypeDef的指针;
  *@return 结果 @ref DRV_SSI_StatusTypeDef
  */
DRV_SSI_StatusTypeDef  DRV_PsramInit(SSI_TypeDef *pssi)
{
	unsigned char temp;
	
	pssi->SSIENR    = 0x00;
	pssi->CTRLR1    = 0x00;
	pssi->CTRLR0    = 0x07;
	pssi->BAUDR     = 0x02;
	pssi->TXFTLR    = 0x00;
	pssi->RXFTLR    = 0x00;
	pssi->SPICTRLR0 = 0x8000;
	pssi->IMR       = 0x00;
	pssi->RXSDR     = 0x00000001;
	pssi->SSIENR    = 0x01;
	
  pssi->DR = PSRAM_RNTERQUAD;
	
	__asm("nop"); __asm("nop"); __asm("nop");

	
	while((pssi->SR&SR_TFE) == 0x00);
	while(pssi->SR&SR_BUSY);

	while(pssi->SR & SR_RFNE)
	{
		temp = pssi->DR;
	}
  
	pssi->SSIENR    = 0x00;
	pssi->SPICTRLR0 = 0x4000021a|(6<<11);//0x4000321a;
	//pssi->BAUDR     = 0x02;
	//pssi->TXFTLR    = 0x00;
	pssi->RXFTLR    = 0x07;
	//pssi->IMR       = 0x00;
	pssi->RXSDR     = 0x00010002;
	pssi->SSIENR    = 0x01;
		 
	PSRAM_CR |= 0x01;

	return DRV_SSI_OK;
}

/**
  *@brief SSI Standard 初始化
  *
  *@param[in]  SSIx 指向SSI_TypeDef的指针;
  *@return 无
  */
void SSI_Standard_Init(SSI_TypeDef *SSIx)
{
	  while(SSIx->SR&SR_BUSY);
    SSIx->SSIENR =  SSI_DISABLE;
	  SSIx->CTRLR1 =  NDF_STD(0);
	  SSIx->CTRLR0 =  SIZE_8_BIT;
	  SSIx->BAUDR  =  STA_BAUDR;
	  SSIx->TXFTLR =  TXFTHR(0)|TFT(0);
	  SSIx->RXFTLR =  RFT(0);
	  SSIx->SPICTRLR0 = NONE; 
	  SSIx->RXSDR=  RSD(2);
	  SSIx->IMR    =  DISABLE;
	  SSIx->SSIENR =  SSI_ENABLE;
	  CS_INIT;
}	

/**
  *@brief 获取SPIFlash状态寄存器1的值
  *
  *@param[in]  SSIx 指向SSI_TypeDef的指针;
  *@param[in]  cmd  获取flash状态的命令字;
  *@return 状态寄存器的值
  */
uint8_t SSI_EFlash_Get_Status(SSI_TypeDef *SSIx,uint8_t cmd)
{ 
	volatile unsigned char retVal;
 CS_LOW;
	SSIx->DR=cmd;
	SSIx->DR=DUMMY_BYTE;	
	__asm("nop");	__asm("nop");	 
	while((SSIx->SR&SR_TFE)!=SR_TFE);
	while(SSIx->SR&SR_BUSY);
	while(SSIx->SR&SR_RFNE)
	{
		retVal=SSIx->DR;
	}	
 CS_HIGH;
	return retVal;
}	

/**
  *@brief SSI SPIFlash写使能 
  *
  *@param[in]  SSIx 指向SSI_TypeDef的指针;
  *@return None
  */
void SSI_EFlash_Write_Enable(SSI_TypeDef *SSIx)
{
	volatile unsigned char status;
	volatile unsigned char temp;
	if((SSI_EFlash_Get_Status(SSIx, GET_SAT1_CMD)&0x02) == 0)
	{
		CS_LOW;
		SSIx->DR=WRITE_EN_CMD;
	
		__asm("nop");	__asm("nop");	 
		
	  while((SSIx->SR&SR_TFE)!=SR_TFE);
	  while(SSIx->SR&SR_BUSY);
		
		while(SSIx->SR&SR_RFNE)
		{
				temp=SSIx->DR;
		}
   CS_HIGH;		
		do
		{
			status=SSI_EFlash_Get_Status(SSIx, GET_SAT1_CMD);		 
		}while(status&0x01);
	}
}	

/**
  *@brief 等待SPIFLASH处于空闲状态
  *
  *@param[in]  SSIx 指向SSI_TypeDef的指针;
  *@return None
  */
void SSI_Wait_SPIFlash_Idle(SSI_TypeDef *SSIx)
{
	 volatile unsigned char status;
	 while(SSIx->SR&SR_BUSY){;}
	 SSI_Standard_Init(SSIx);  
	 do
	 {
	   status=SSI_EFlash_Get_Status(SSIx, GET_SAT1_CMD);		 	 
	 }while(status&0x01);	
}

/**
  *@brief ssi单线模式，通过dma往flash中写数据
  *@param[in] SSIx  指向SSI_TypeDef结构体的指针,此结构体包含了SSI模块的配置信息;
  *@param[in] psend 发送数据地址
  *@param[in] addr  源地址;
  *@param[in] length  传输数据长度;
  *@param[in] binten  是否开启中断;
  *@return 无
  */

 void SSI_STD_DMA_Program(SSI_TypeDef *SSIx, uint8_t* psend, uint32_t addr, uint32_t length, bool binten)
{
	  SSI_Standard_Init(SSIx);
		SSI_EFlash_Write_Enable(SSIx);
	  DMA_REG_Init(DMAC2_BASE_ADDR,DMA_CH(0));
    dma_ssi_m2p_start(psend, (uint8_t *)(&(SSIx->DR)),length, binten);
	  CS_LOW;
		DRV_SSI_STD_DMA_Trig(SSIx,PAGE_PROG_CMD,addr,DMACR_TDMAE);
		dma_ssi_wait(binten);
    while(SSIx->SR&SR_BUSY){;} //add by zjhuang  20200824
	  CS_HIGH;  //当波特率4分频的情况下，会存在编程还没有写完，CS已经拉高，可加上上面一句可以解决问题
	  SSIx->DMACR = 0;
		SSI_Wait_SPIFlash_Idle(SSIx);	
}

/**
  *@brief ssi单线模式下，从flash中读数据
  *@param[in] SSIx  指向SSI_TypeDef结构体的指针,此结构体包含了SSI模块的配置信息;
  *@param[in] psend 发送数据地址
  *@param[in] addr  源地址;
  *@param[in] length  传输数据长度;
  *@param[in] binten  是否开启中断;
  *@return 无
  */
void SSI_STD_DMA_Read(SSI_TypeDef *SSIx,  uint8_t* pread, uint32_t addr, uint32_t length, bool binten)
{ 
	uint32_t num=0;
	SSI_Standard_Init(SSIx);	
  DMA_REG_Init(DMAC2_BASE_ADDR,DMA_CH(0));	
	dma_ssi_p2m_lli_start((uint8_t *)(&(SSIx->DR)),pread, length+4, binten);
	CS_LOW;
	DRV_SSI_STD_DMA_Trig(SSIx,READ_CMD,addr,DMACR_RDMAE);
	num=length;
	while( get_dma_flag(binten)!=1)
	 {
	 if( (SSIx->SR&SR_TFNF)&&(num>0) )
			 {
			    SSIx->DR=DUMMY_BYTE;
				  num--;
			 }
	 }
	clear_dma_flag(binten);
	CS_HIGH;
	SSIx->DMACR = 0x00;
}


