#include "omw_gpadc.h"



void omw_gpadc_ldo_init(void);


void omw_gpadc_init( GPADC_InitTypeDef* ADC_InitStruct,uint32_t * gpadc_base_addr)
{	
    omw_gpadc_ldo_init();
	
    gpadc_base_addr[OMW_GPADC_CTRL]  = (ADC_InitStruct->gpadc_att_sel << 13) | (ADC_InitStruct->gpadc_diff_en << 12) |
    (8 << 8) | (ADC_InitStruct->gpadc_vin_sel << 4) | (ADC_InitStruct->gpadc_vip_sel);

    gpadc_base_addr[OMW_GPADC_ACTION] = (ADC_InitStruct->gpadc_avg_win << 12) + (ADC_InitStruct->gpadc_timer_sel << 4) + 
    (ADC_InitStruct->gpadc_timer_mode << 3) +(ADC_InitStruct->gpadc_cont_mode <<2) + (ADC_InitStruct->gpadc_samp_en << 1) + 
    (ADC_InitStruct->gpadc_dma_en); 
    
    gpadc_base_addr[OMW_GPADC_CFG1]   = (ADC_InitStruct->gpadc_int_interval << 8) + (ADC_InitStruct->gpadc_bk_num << 6)+
    (ADC_InitStruct->gpadc_start_bk << 4) + (ADC_InitStruct->gpadc_signext << 2) + (ADC_InitStruct->gpadc_format << 1) +  (ADC_InitStruct->gpadc_store_mode);

    gpadc_base_addr[OMW_GPADC_CLK_CRTL] = (ADC_InitStruct->gpadc_clk_pre << 16) + (ADC_InitStruct->gpadc_clk_div << 8) +
    (ADC_InitStruct->gpadc_clk_out_pol << 5) + (ADC_InitStruct ->gpadc_clk_out_inv << 4) + (ADC_InitStruct ->gpadc_clk_samp_inv << 3) + 
    (ADC_InitStruct->gpadc_clk_en << 2) + (ADC_InitStruct->gpadc_clk_autocg << 1) + (ADC_InitStruct->gpadc_clk_sel);

}

void omw_gpadc_structinit(GPADC_InitTypeDef* ADC_InitStruct)
{
    ADC_InitStruct->gpadc_att_sel = 3;
    ADC_InitStruct->gpadc_diff_en = 0;
    ADC_InitStruct->gpadc_vin_sel= 0xC;
    ADC_InitStruct->gpadc_vip_sel = 0XC;
	
    ADC_InitStruct->gpadc_avg_win = 0;
    ADC_InitStruct->gpadc_timer_sel = 0;
    ADC_InitStruct->gpadc_timer_mode = 0;
    ADC_InitStruct->gpadc_cont_mode = 0;
    ADC_InitStruct->gpadc_samp_en = 0;
    ADC_InitStruct->gpadc_dma_en = 0;
	
    ADC_InitStruct->gpadc_int_interval = 0;
    ADC_InitStruct->gpadc_bk_num = 0;
    ADC_InitStruct->gpadc_start_bk = 0;
    ADC_InitStruct->gpadc_signext = 0;
    ADC_InitStruct->gpadc_format = 0;
    ADC_InitStruct->gpadc_store_mode = 0;
    
    ADC_InitStruct->gpadc_clk_pre = 0;
    ADC_InitStruct->gpadc_clk_div = 0;
    ADC_InitStruct->gpadc_clk_out_pol = 0;
    ADC_InitStruct->gpadc_clk_out_inv = 0;
    ADC_InitStruct->gpadc_clk_samp_inv = 0;
    ADC_InitStruct->gpadc_clk_en = 0;
    ADC_InitStruct->gpadc_clk_autocg = 0;
    ADC_InitStruct->gpadc_clk_sel = 0;
}

void omw_gpadc_cmd(FunctionalState NewState,uint32_t * gpadc_base_addr)
{
    if (NewState != DISABLE)
		gpadc_base_addr[OMW_GPADC_EN] |= (uint32_t)(ENABLE << 1) ;
	else
		gpadc_base_addr[OMW_GPADC_EN] &= ~((uint32_t)(ENABLE << 1)) ;
}


void omw_gpadc_itconfig(FunctionalState NewState,uint32_t * gpadc_base_addr)
{
  if (NewState != DISABLE)
		gpadc_base_addr[OMW_GPADC_INT_CRTL] |= (uint32_t)(ENABLE << 17) ;
	else
		gpadc_base_addr[OMW_GPADC_INT_CRTL] &= ~((uint32_t)(ENABLE << 17)) ;
}

void omw_gpadc_dma_itconfig(FunctionalState NewState,uint32_t * gpadc_base_addr)
{
  if (NewState != DISABLE)
		gpadc_base_addr[OMW_GPADC_INT_CRTL] |= (uint32_t)(ENABLE << 16) ;
	else
		gpadc_base_addr[OMW_GPADC_INT_CRTL] &= ~((uint32_t)(ENABLE << 16)) ;
}

uint16_t omw_gpadc_get_dma_point(void)
{
  uint16_t flag = (*(uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_INT_CRTL << 2))) | (0x7FF0000) >> 16;
  return flag;
}

FlagStatus omw_get_gpadc_itstatus(void)
{
  ITStatus bitstatus = RESET;
	if(((*(volatile uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_INT_CRTL << 2))) & (SET << 9)) != RESET)
		bitstatus = SET;
	else
		bitstatus = RESET;
	return bitstatus;
}

FlagStatus omw_get_gpadc_dma_itstatus(void)
{
  ITStatus bitstatus = RESET;
	if(((*(volatile uint32_t*)(OMW_GPADC_BASE + (OMW_GPADC_INT_CRTL << 2 ))) & (SET << 8)) != RESET)
		bitstatus = SET;
	else
		bitstatus = RESET;
	return bitstatus;
}



uint32_t omw_gpadc_get_samp(void){
    int t = 0;
	int count_mode = 0;
    // trigger irq
    count_mode = (*(volatile uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_ACTION << 2)));
	count_mode = (count_mode >> 2) & 0x01;

    if(count_mode==0) (*(volatile uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_ACTION << 2))) |= 0x80000000;

    // wait samp
//	t = (*(uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_INT_CRTL << 2)));
//	t = t & 2;
//	t = (t >> 1);
//    while(~t)
//	{
//		t = (*(uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_INT_CRTL << 2)));
//		t = t & 2;
//		t = (t >> 1);
//	}
    while (1)
	{
		t = (*(volatile uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_INT_CRTL << 2)));
		t = t & 2;
		if(t == 2)
			break;
		
	}	
    t =(*(volatile uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_SAMP << 2 )));
    (*(volatile uint32_t*)(GPADC_ANA_BASE + (OMW_GPADC_INT_CRTL << 2))) |= 2;
    return t;
}




void omw_gpadc_ldo_init(void){
	// Enable LDO
    *(volatile int *)(0x42002004) |= 0x201;
    // AD/DA LDO voltage

    *(volatile int *)(0x40080104) &= 0xffffe0ff;
	*(volatile int *)(0x40080104) |= 0x600;
}