/**
  **********************************************************************************
  *@file    dma2d_drv.c
  *@author  Product application department
  *@version V1.0
  *@date    2020.05.25
  *@brief   DMA2D模块DRV层驱动.
  *
  @verbatim
  ===================================================================================
                                  ##### 更新 #####
  ===================================================================================
  [..] 更新时间:
  [..] 更新人:
  [..] 更新内容:
        1. nothing.
  @endverbatim
*/
#include "dma2d_drv.h"
 
/*** 全局变量定义 ***************************************************************/
/**@ volatile
  *@{
  */

/**@
  *@}
  */
/**@ static
  *@{
  */

/**@
  *@}
  */
/*** 常量定义 *******************************************************************/
/**@ const
  *@{
  */
	
void DRV_DMA2D_SoftReset(void)
{
	*(volatile unsigned int*)0x400040B0 |= (1<<8);
	*(volatile unsigned int*)0x400040B0 &= ~(1<<8);
}

void DRV_DMA2D_ClutInit(uint32_t* addr, int32_t len)
{
	int32_t i;
	
	for(i = 0; i < len; i++)
	{
		addr[i] = i | (i << 8) | (i << 16) | (i << 24);
	}
}

 
void DRV_DMA2D_SetAlphaCmp(DMA2D_TypeDef *pdma2d,uint8_t val)
{
	pdma2d->CR |= ALPHA_CMP_EN;
	pdma2d->OPFCCR = (pdma2d->OPFCCR & (~ALPHA_CMP_VAL_MASK)) | (val << 24);
 
}
 
void DRV_DMA2D_FgClutLoad(DMA2D_TypeDef *pdma2d , DMA2D_InitTypeDef *pinit)
{
	pdma2d->FGCMAR = pinit->ClutFgAddr;
	pdma2d->FGPFCCR = ((pdma2d->FGPFCCR) & ~PFCCR_CS_MASK) |
				(((pinit->ClutFgSize-1) << 8) & PFCCR_CS_MASK) | ((pinit->ClutFgFormat << 4) & PFCCR_CCM);
	
	pdma2d->FGPFCCR |= PFCCR_START;
	while(pdma2d->FGPFCCR & PFCCR_START);	//wait done
}
 


void DRV_DMA2D_BgClutLoad(DMA2D_TypeDef *pdma2d , DMA2D_InitTypeDef *pinit)
{
	pdma2d->BGCMAR = pinit->ClutBgAddr;
	pdma2d->BGPFCCR = ((pdma2d->BGPFCCR) & ~PFCCR_CS_MASK) |
				(((pinit->ClutBgSize-1) << 8) & PFCCR_CS_MASK) | ((pinit->ClutBgFormat << 4) & PFCCR_CCM);
	
	pdma2d->BGPFCCR |= PFCCR_START;
	while(pdma2d->BGPFCCR & PFCCR_START);	//wait done
}


/**
 *@brief 初始化DMA2D模块的设置.
 *
 *@param[in] pdma2d  指DMA2D_TypeDef结构体的指针;
 *@param[in] pinit  指DMA2D_InitTypeDef结构体的指针;
 *@return DRV_DMA2D_Init @ref DRV_DMA2D_StatusTypeDef
 */
DRV_DMA2D_StatusTypeDef DRV_DMA2D_PfcHard(DMA2D_TypeDef *pdma2d, DMA2D_InitTypeDef *pinit)
{
	uint32_t timeout = 0;
	

	pdma2d->CR = MODE_MEM2MEM_PFC;	//mem2mem with PFC
	if(pinit->EnableIE == ENABLE)
	{ 
    NVIC_Init(3, 3, DMA2D_IRQn, 2);
		pinit->G_flg_dma2d_done = 0;
	  pdma2d->CR |= CR_TCIE;
	}
	else
	{
	 pdma2d->CR &= ~CR_TCIE;
	}
	pdma2d->FGPFCCR =pinit->InFgFormat  ;				//FG color mode
	pdma2d->FGMAR =pinit->InFgAddr  ;
	pdma2d->OMAR =pinit->OutAddr  ;
	pdma2d->NLR = ((pinit->Width & 0x3FFF) << 16) | (pinit->Height & 0xFFFF);
	pdma2d->FGOR = pinit->InFgOffset & 0x3FFF;
	pdma2d->OPFCCR = pinit->OutFormat;
	pdma2d->OOR = pinit->OutOffset & 0x3FFF;
	DRV_DMA2D_SetAlphaCmp(pdma2d,128);
	pdma2d->CR |= DMA2D_START;				       //start DMA2D
if(pinit->EnableIE == ENABLE)
	{ 	 
	  while(pinit->G_flg_dma2d_done == 0); 
	}
	else
	{
		while((DMA2D->ISR & ISR_TCIF) == 0)
		{
			timeout++;
			if(timeout>0X1FFFFF)break;
		}
		DMA2D->IFCR |= IFCR_CTCIF;
 }
}

 
void DRV_DMA2D_Reg2Mem(DMA2D_TypeDef *pdma2d, DMA2D_InitTypeDef *pinit)
{
	unsigned int timeout = 0;
	

	DMA2D->CR = MODE_REG2MEM;		//mode REG2MEM
	if(pinit->EnableIE == ENABLE)
	{  
		NVIC_Init(3, 3, DMA2D_IRQn, 2);
		pinit->G_flg_dma2d_done = 0;
	  pdma2d->CR |= CR_TCIE;
	}
	else
	{
	 pdma2d->CR &= ~CR_TCIE;
	}

	DMA2D->CR |= CR_BURST_TYPE;

	DMA2D->OPFCCR = pinit->OutFormat;					//color mode
	DMA2D->OCOLR = pinit->RegARGBColor; 			  //color;
	DMA2D->OMAR = pinit->OutAddr;
	DMA2D->NLR = ((pinit->Width  & 0x3FFF) << 16) | (pinit->Height & 0xFFFF);
	DMA2D->OOR = pinit->OutOffset  & 0x3FFF;

	DMA2D->CR |= DMA2D_START;		//start DMA2D
if(pinit->EnableIE == ENABLE)
	{ 	 
	  while(pinit->G_flg_dma2d_done == 0); 
	}
	else
	{
		while((DMA2D->ISR & ISR_TCIF) == 0)
		{
			timeout++;
			if(timeout>0X1FFFFF)break;
		}
		DMA2D->IFCR |= IFCR_CTCIF;
 }
}

 
void DRV_DMA2D_Mem2Mem(DMA2D_TypeDef *pdma2d, DMA2D_InitTypeDef *pinit)
{
	unsigned int timeout = 0;

	pdma2d->CR = MODE_MEM2MEM; 	//mem2mem
 
	if(pinit->EnableIE == ENABLE)
	{  
		NVIC_Init(3, 3, DMA2D_IRQn, 2);
		pinit->G_flg_dma2d_done = 0;
	  pdma2d->CR |= CR_TCIE;
	}
	else
	{
	 pdma2d->CR &= ~CR_TCIE;
	}
 
	pdma2d->CR |= CR_BURST_TYPE;

	pdma2d->FGPFCCR = pinit->InFgFormat;				//color mode
	pdma2d->FGMAR = pinit->InFgAddr  ;
	pdma2d->OMAR = pinit->OutAddr;
	pdma2d->NLR = ((pinit->Width & 0x3FFF) << 16) | (pinit->Height & 0xFFFF);
	pdma2d->FGOR = pinit->InFgOffset & 0x3FFF;
	pdma2d->OOR = pinit->OutOffset & 0x3FFF;

	pdma2d->CR |= DMA2D_START;		//start DMA2D
if(pinit->EnableIE == ENABLE)
	{ 	 
	  while(pinit->G_flg_dma2d_done == 0); 
	}
	else
	{
		while((DMA2D->ISR & ISR_TCIF) == 0)
		{
			timeout++;
			if(timeout>0X1FFFFF)break;
		}
		DMA2D->IFCR |= IFCR_CTCIF;
 }
}
 
				
DRV_DMA2D_StatusTypeDef DRV_DMA2D_BlendHard(DMA2D_TypeDef *pdma2d, DMA2D_InitTypeDef *pinit)			
{
	unsigned int timeout = 0;
	
 			//stop DMA2D
  pdma2d->CR = MODE_MEM2MEM_BLEND;	//mem2mem with blend
	if(pinit->EnableIE == ENABLE)
	{  
		NVIC_Init(3, 3, DMA2D_IRQn, 2);
		pinit->G_flg_dma2d_done = 0;
	  pdma2d->CR |= CR_TCIE;
	}
	else
	{
	 pdma2d->CR &= ~CR_TCIE;
	}

	pdma2d->CR |= CR_BURST_TYPE;

	pdma2d->FGPFCCR = pinit->InFgFormat;				//FG color mode
	pdma2d->FGMAR = pinit->InFgAddr;
	pdma2d->BGPFCCR =pinit->InBgFormat  ;				//BG color mode
	pdma2d->BGMAR = pinit->InBgAddr;
	pdma2d->OMAR = pinit->OutAddr;
	pdma2d->NLR = ((pinit->Width & 0x3FFF) << 16) | (pinit->Height & 0xFFFF);
	pdma2d->FGOR = pinit->InFgOffset & 0x3FFF;
	pdma2d->BGOR = pinit->InBgOffset & 0x3FFF;
	pdma2d->OPFCCR = pinit->OutFormat;
	pdma2d->OOR = pinit->OutOffset & 0x3FFF;
	DRV_DMA2D_SetAlphaCmp(pdma2d,128);
	pdma2d->CR |= DMA2D_START;				//start DMA2D
if(pinit->EnableIE == ENABLE)
	{ 	 
	  while(pinit->G_flg_dma2d_done == 0); 
	}
	else
	{
		while((DMA2D->ISR & ISR_TCIF) == 0)
		{
			timeout++;
			if(timeout>0X1FFFFF)break;
		}
		DMA2D->IFCR |= IFCR_CTCIF;
 }
 
}






