/******************** (C) COPYRIGHT 2021 SONiX *******************************
* COMPANY:			SONiX
* DATE:					2021/07
* AUTHOR:				SA1
* IC:						SN32F800
* DESCRIPTION:	DAC related functions.
*____________________________________________________________________________
* REVISION	Date				User		Description
*	1.0				2021/07/09	SA1			1. First release
*																2. Set SN_ADC->ADM2 to 3 if DAC VIREF is used.
*
*____________________________________________________________________________
* 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 <SN32F800_Def.h>
#include "DAC.h"
#include "..\ADC\ADC.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		: DAC_IRQHandler
* Description	: ISR of DAC interrupt
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
__irq void DAC_IRQHandler(void)
{
	uint32_t iwRisStatus;
	
	iwRisStatus = SN_CT16B0->RIS;	//Save the interrupt status.
	
	if (iwRisStatus & mskDAC0IF)
	{
		SN_DAC->IC = mskDAC0IC;
	}
	if (iwRisStatus & mskDAC1IF)
	{
		SN_DAC->IC = mskDAC1IC;
	}	
	if (iwRisStatus & mskDAC2IF)
	{
		SN_DAC->IC = mskDAC2IC;
	}
	if (iwRisStatus & mskDAC3IF)
	{
		SN_DAC->IC = mskDAC3IC;
	}
}

/*****************************************************************************
* Function		: DAC_Init
* Description	: Initialization of DAC0/1/2/3
* Input			: bDAC_Ch - DAC_Channel0, DAC_Channel1, DAC_Channel2, DAC_Channel3
*							SDAC_INIT_TYPE* - Point to a DAC confighration struct
* Output		: None
* Return		: None
* Note			: Set SN_ADC->ADM2 to 3 if DAC VIREF is used!
*****************************************************************************/
void DAC_Init(uint8_t bDAC_Ch, SDAC_INIT_TYPE* sDAC_InitStruct)
{
	__DAC_ENABLE_DACHCLK;
	
	SN_DAC->VIREF = ((sDAC_InitStruct->bDAC_VHS << 16)  | sDAC_InitStruct->bDAC_VIREF);
	
	//Set SN_ADC->ADM2 to 3 if DAC VIREF is used.
	if (SN_DAC->VIREF_b.VHS0 == DAC_VHS_VIREF)
	{
		__ADC_ENABLE_HCLK
		SN_ADC->ADM2 = 3;														//Must set SN_ADC->ADM2 to 3 if ADC/CMP/DAC interval voltage reference is used.
	}
	
	SN_DAC->TGCTRL |= (sDAC_InitStruct->bDAC_Clock_Source << (bDAC_Ch * 4));
	
	SN_DAC->CLK |= (sDAC_InitStruct->bDAC_Clock_Div << (bDAC_Ch * 4));
	
	if (sDAC_InitStruct->bDAC_IE_Enable)
	{
		SN_DAC->IC = (ENABLE << bDAC_Ch);
		SN_DAC->IE |= (ENABLE << bDAC_Ch);
		DAC_NvicEnable();
	}
}

/*****************************************************************************
* Function		: DAC_ChannelCtrl
* Description	: Specifies the DAC and output buffer enable or not
* Input			: bDAC_Ch - DAC_Channel0, DAC_Channel1, DAC_Channel2, DAC_Channel3
*							bDAC_BufEn - ENABLE, DISABLE
*							bDAC_En - ENABLE, DISABLE
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void DAC_ChannelCtrl(uint8_t bDAC_Ch, uint8_t bDAC_BufEn, uint8_t bDAC_En)
{
	if (bDAC_BufEn == ENABLE)
	{
		SN_DAC->ADM |= (bDAC_BufEn << (bDAC_Ch + 8));
	}
	else
	{
		SN_DAC->ADM &= ~(bDAC_BufEn << (bDAC_Ch + 8));
	}
	if (bDAC_En == ENABLE)
	{
		SN_DAC->ADM |= (bDAC_En << bDAC_Ch);
	}
	else
	{
		SN_DAC->ADM &= ~(bDAC_En << bDAC_Ch);
	}
}

/*****************************************************************************
* Function		: DAC_SetData
* Description	: Specifies the DAC data
* Input			: bDAC_Ch - DAC_Channel0, DAC_Channel1, DAC_Channel2, DAC_Channel3
*							hwDAC_Data - 12-bit DAC data
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void DAC_SetData(uint8_t bDAC_Ch, uint16_t hwDAC_Data)
{
	switch(bDAC_Ch)
  {
		case DAC_Channel0: SN_DAC->DATACTRL0 = (SN_DAC->DATACTRL0 & 0xFFFF0000) | (hwDAC_Data <<  0); break;
		case DAC_Channel1: SN_DAC->DATACTRL0 = (SN_DAC->DATACTRL0 & 0x0000FFFF) | (hwDAC_Data << 16); break;
		case DAC_Channel2: SN_DAC->DATACTRL1 = (SN_DAC->DATACTRL1 & 0xFFFF0000) | (hwDAC_Data <<  0); break;
		case DAC_Channel3: SN_DAC->DATACTRL1 = (SN_DAC->DATACTRL1 & 0x0000FFFF) | (hwDAC_Data << 16); break;
		default: break;
  }

}

/*****************************************************************************
* Function		: DAC_NvicEnable
* Description	: Enable DAC interrupt
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void DAC_NvicEnable(void)
{
	NVIC_ClearPendingIRQ(DAC_IRQn);
	NVIC_EnableIRQ(DAC_IRQn);
	NVIC_SetPriority(DAC_IRQn, 0);			// Set interrupt priority (default)
}

/*****************************************************************************
* Function		: DAC_NvicDisable
* Description	: Disable DAC interrupt
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void DAC_NvicDisable(void)
{
	NVIC_DisableIRQ(DAC_IRQn);
}
