/**************************************************************************************************
  Filename:       hal_adf4113.c
  Revised:        $Date: 2013-11-17 $
  Revision:       $Revision:  $
  Description:   This file contains the interface to the ADF4113 frequency synthesizer.
**************************************************************************************************/
#include "pll_4113.h"
void ADF4113_Module_Ctrl(PLL_Setting_st pll,uint32_t R0,uint32_t R1,uint32_t R2);

uint32_t N_Counter_Latch_Create(uint16_t _ACOUNTER,uint16_t _BCOUNTER,uint8_t _CPGAIN);

#define ADF4113_PRESCALE8         0
#define ADF4113_PRESCALE16        1
#define ADF4113_PRESCALE32        2
#define ADF4113_PRESCALE64        3
// ADF4113 Prescale value for minimum required division ratio
#define ADF4113_PRE8_MIN_N        56
#define ADF4113_PRE16_MIN_N       240
#define ADF4113_PRE32_MIN_N       992
#define ADF4113_PRE64_MIN_N       4032
// Frequency Settings
// Initally, the synthesizer will operate at 2450 MHz
#define ADF4113_CH_STEP          50000
#define HAL_SYN_INVALID_PRESCALE  0x04
#define ADF4113_REF_FREQ_MHZ    13000000
PLL_Setting_st ADF4113_1_8G_DL = {
    PLL_CLK_GPIO_Port,
    PLL_CLK_Pin,
    PLL_DATA_GPIO_Port,
    PLL_DATA_Pin,
    PLL_EN_1_8G_DL_GPIO_Port,    
    PLL_EN_1_8G_DL_Pin,
};
PLL_Setting_st ADF4113_1_8G_UL = {
    PLL_CLK_GPIO_Port,
    PLL_CLK_Pin,
    PLL_DATA_GPIO_Port,
    PLL_DATA_Pin,
    PLL_EN_1_8G_UL_GPIO_Port,    
    PLL_EN_1_8G_UL_Pin,
};
PLL_Setting_st ADF4113_2_1G_DL = {
    PLL_CLK_GPIO_Port,
    PLL_CLK_Pin,
    PLL_DATA_GPIO_Port,
    PLL_DATA_Pin,
    PLL_EN_2_1G_DL_GPIO_Port,    
    PLL_EN_2_1G_DL_Pin,
};
PLL_Setting_st ADF4113_2_1G_UL = {
    PLL_CLK_GPIO_Port,
    PLL_CLK_Pin,
    PLL_DATA_GPIO_Port,
    PLL_DATA_Pin,
    PLL_EN_2_1G_UL_GPIO_Port,    
    PLL_EN_2_1G_UL_Pin,
};



// Error Code
typedef struct{
    uint16_t B;
    uint16_t P;
    uint16_t A;   
    uint16_t N;       
}Adf4113_st;
void ADF4113_Initialize(void){
    ADF4113_Module_Ctrl(ADF4113_1_8G_DL,0x000410,0x03E801,0x9F8092);
    HAL_Delay(1);
    ADF4113_Module_Ctrl(ADF4113_1_8G_UL,0x000410,0x038D31,0x9f8092);
    HAL_Delay(1);
    ADF4113_Module_Ctrl(ADF4113_2_1G_DL,0x410,0x4DE71,0x9F8092);
    HAL_Delay(1);
    ADF4113_Module_Ctrl(ADF4113_2_1G_UL,0x000410,0x59A31,0x9f8092);
}
uint8_t halSynSetFreq(uint32_t rf_Freq)
{
    uint32_t  R, B;
    uint32_t  A, P, p_mode;
    uint32_t  N_val = 0;
    N_val = (rf_Freq / ADF4113_CH_STEP);
    if( N_val < ADF4113_PRE8_MIN_N) { 
        return HAL_SYN_INVALID_PRESCALE; 
    } else if(( N_val> ADF4113_PRE8_MIN_N) && (N_val < ADF4113_PRE16_MIN_N)) { 
        P = 8;  
        p_mode = ADF4113_PRESCALE8;
    } else if(( N_val > ADF4113_PRE16_MIN_N) && (N_val < ADF4113_PRE32_MIN_N)) { 
        P = 16;
        p_mode = ADF4113_PRESCALE16;
        
    } else if((N_val > ADF4113_PRE32_MIN_N) && ( N_val < ADF4113_PRE64_MIN_N)) { 
        P = 32;
        p_mode = ADF4113_PRESCALE32;
        
    } else if( N_val > ADF4113_PRE64_MIN_N) { 
        P = 64; 
        p_mode = ADF4113_PRESCALE64;
    }
    P = 32;
    B = N_val / P;
    A = N_val -(B * P);
#ifdef DEBUG_PRINT
    printf("FREQ:%f Mhz  B : %d , A  : %d    N_VAL  : %d \r\n",(float)(rf_Freq/1000000),B,A,N_val);
    printf("YJ 4113 : %x \r\n",N_Counter_Latch_Create(A,B,0));
#endif /* DEBUG_PRINT */
}
uint32_t N_Counter_Latch_Create(uint16_t _ACOUNTER,uint16_t _BCOUNTER,uint8_t _CPGAIN){
    uint32_t ret = 0;
    uint32_t shift_bit = 0x01;
    uint8_t control_bit = 1;
    uint8_t i = 0;
    uint8_t reserve = 0;
#ifdef DEBUG_PRINT
    printf("_ACOUNTER : %d _BCOUNTER : %d \r\n",_ACOUNTER,_BCOUNTER);

    printf("\r\nLINE : %d  ret : %x\r\n",__LINE__,ret);
#endif /* DEBUG_PRINT */
    for(i = 0; i < 2; i++){
        if(control_bit & 0x01)
            ret += shift_bit << i;
        control_bit = control_bit >> 1;
    }
#ifdef DEBUG_PRINT
    printf("\r\nLINE : %d  ret : %x\r\n",__LINE__,ret);
#endif /* DEBUG_PRINT */
    for(i = 2; i < 8; i++){
        if(_ACOUNTER & 0x01)
            ret += shift_bit << i;
        _ACOUNTER = _ACOUNTER >> 1;
    }  
#ifdef DEBUG_PRINT
    printf("\r\nLINE : %d  ret : %x\r\n",__LINE__,ret);
#endif /* DEBUG_PRINT */
    for(i = 8; i < 21; i++){
        if(_BCOUNTER & 0x01)
            ret += shift_bit << i;
        _BCOUNTER = _BCOUNTER >> 1;
    }      
#ifdef DEBUG_PRINT
    printf("\r\nLINE : %d  ret : %x\r\n",__LINE__,ret);
#endif /* DEBUG_PRINT */
    if(_CPGAIN & 0x01)
            ret += shift_bit << i++;
    for(i = 22; i < 24; i++){
        if(reserve & 0x01)
            ret += shift_bit << i;
        reserve = reserve >> 1;
    }   
#ifdef DEBUG_PRINT
    printf("\r\nLINE : %d  ret : %x\r\n",__LINE__,ret);
#endif /* DEBUG_PRINT */
    return ret;
}
void ADF4113_Module_Ctrl(PLL_Setting_st pll,uint32_t R0,uint32_t R1,uint32_t R2){
    R2 = R2 & 0xFFFFFF;
    R1 = R1 & 0xFFFFFF;
    R0 = R0 & 0xFFFFFF;
    
    HAL_GPIO_WritePin(pll.PLL_CLK_PORT, pll.PLL_CLK_PIN, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(pll.PLL_DATA_PORT, pll.PLL_DATA_PIN, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(pll.PLL_ENABLE_PORT, pll.PLL_ENABLE_PIN, GPIO_PIN_RESET);
    /*   R2 Ctrl    */
     for(int i =0; i < 24; i++){
         if(R2 & 0x800000){
#ifdef DEBUG_PRINT
            printf("1");
#endif /* DEBUG_PRINT */
             HAL_GPIO_WritePin(pll.PLL_DATA_PORT, pll.PLL_DATA_PIN, GPIO_PIN_SET);
         }
         else{
#ifdef DEBUG_PRINT
            printf("0");
#endif /* DEBUG_PRINT */
             HAL_GPIO_WritePin(pll.PLL_DATA_PORT, pll.PLL_DATA_PIN, GPIO_PIN_RESET);
         }
          HAL_GPIO_WritePin(pll.PLL_CLK_PORT, pll.PLL_CLK_PIN, GPIO_PIN_SET);
         Pol_Delay_us(10);
          HAL_GPIO_WritePin(pll.PLL_CLK_PORT, pll.PLL_CLK_PIN, GPIO_PIN_RESET);
         R2 = ((R2 << 1) & 0xFFFFFF);
     }
#ifdef DEBUG_PRINT
     printf("\r\n");
#endif /* DEBUG_PRINT */
     HAL_GPIO_WritePin(pll.PLL_ENABLE_PORT, pll.PLL_ENABLE_PIN, GPIO_PIN_SET);
     Pol_Delay_us(10);
     HAL_GPIO_WritePin(pll.PLL_ENABLE_PORT, pll.PLL_ENABLE_PIN, GPIO_PIN_RESET);
        /*   R0 Ctrl    */
   
    for(int i =0; i < 24; i++){
        if(R0 & 0x800000){
            HAL_GPIO_WritePin(pll.PLL_DATA_PORT, pll.PLL_DATA_PIN, GPIO_PIN_SET);
#ifdef DEBUG_PRINT
            printf("1");
#endif /* DEBUG_PRINT */
        }
        else{
            HAL_GPIO_WritePin(pll.PLL_DATA_PORT, pll.PLL_DATA_PIN, GPIO_PIN_RESET);
#ifdef DEBUG_PRINT
            printf("0");
#endif /* DEBUG_PRINT */
        }
         HAL_GPIO_WritePin(pll.PLL_CLK_PORT, pll.PLL_CLK_PIN, GPIO_PIN_SET);
        Pol_Delay_us(10);
         HAL_GPIO_WritePin(pll.PLL_CLK_PORT, pll.PLL_CLK_PIN, GPIO_PIN_RESET);
        R0 = ((R0 << 1) & 0xFFFFFF);
    }  
#ifdef DEBUG_PRINT
        printf("\r\n");
#endif /* DEBUG_PRINT */
     HAL_GPIO_WritePin(pll.PLL_ENABLE_PORT, pll.PLL_ENABLE_PIN, GPIO_PIN_SET);
     
     Pol_Delay_us(10);
     HAL_GPIO_WritePin(pll.PLL_ENABLE_PORT, pll.PLL_ENABLE_PIN, GPIO_PIN_RESET);    
     /*   R1 Ctrl    */
    for(int i =0; i < 24; i++){
        if(R1 & 0x800000){
#ifdef DEBUG_PRINT
            printf("1");
#endif /* DEBUG_PRINT */
            HAL_GPIO_WritePin(pll.PLL_DATA_PORT, pll.PLL_DATA_PIN, GPIO_PIN_SET);
        }
        else{
#ifdef DEBUG_PRINT
            printf("0");            
#endif /* DEBUG_PRINT */
            HAL_GPIO_WritePin(pll.PLL_DATA_PORT, pll.PLL_DATA_PIN, GPIO_PIN_RESET);
        }
         HAL_GPIO_WritePin(pll.PLL_CLK_PORT, pll.PLL_CLK_PIN, GPIO_PIN_SET);
        Pol_Delay_us(10);
         HAL_GPIO_WritePin(pll.PLL_CLK_PORT, pll.PLL_CLK_PIN, GPIO_PIN_RESET);
        R1 = ((R1 << 1) & 0xFFFFFF);
    }
#ifdef DEBUG_PRINT
        printf("\r\n");
#endif /* DEBUG_PRINT */
    HAL_GPIO_WritePin(pll.PLL_ENABLE_PORT, pll.PLL_ENABLE_PIN, GPIO_PIN_SET);
    Pol_Delay_us(10);
    HAL_GPIO_WritePin(pll.PLL_ENABLE_PORT, pll.PLL_ENABLE_PIN, GPIO_PIN_RESET);

}
