예제 #1
0
파일: AD9643.c 프로젝트: DrSutherland/no-OS
/***************************************************************************//**
 * @brief Checks if the DCO is locked
 *
 * @return Returns 1 if the DCO is locked, 0 otherwise.
*******************************************************************************/
int32_t ad9643_is_dco_locked()
{
	int32_t ret = -1, cnt;
	uint32_t stat;

	ad9643_testmode_set(0x2, AD9643_TEST_MODE_PN23_SEQ);
	ad9643_testmode_set(0x1, AD9643_TEST_MODE_PN9_SEQ);
    ADC_Core_Write(ADC_CORE_PN_ERR_CTRL, ADC_CORE_PN23_1_EN | ADC_CORE_PN9_0_EN);

    ad9643_read(AD9643_REG_DCO_OUTPUT_DELAY);

    ADC_Core_Write(ADC_CORE_ADC_STAT, ADC_CORE_ADC_STAT_MASK);

    delay_us(1000);

	ADC_Core_Read(ADC_CORE_ADC_STAT, &stat);

    if(!( stat & 0x3c))
    {
        ret = 0;
    }

	ad9643_testmode_set(0x3, AD9643_TEST_MODE_OFF);

	return ret < 0 ? 0 : 1;
}
예제 #2
0
파일: xcomm.c 프로젝트: TheBigCheese/no-OS
/**************************************************************************//**
* @brief Calibrates the ADC DCO clock delay 
* 
* @return If success, returns DCO clock delay code. If the DCO clock is
* 		  inverted 0x100 is added to the returned DCO value
*		  if error,return -1
******************************************************************************/
int32_t XCOMM_CalibrateAdcDco(void)
{
	int32_t ret;

	ADC_Core_Write(ADC_CORE_DMA_CHAN_SEL,0x00);

	ad9643_dco_clock_invert(0);
	ret = ad9643_dco_calibrate_2c();

	ADC_Core_Write(ADC_CORE_DMA_CHAN_SEL,0x02);

	return ret;
}
예제 #3
0
파일: AD9643.c 프로젝트: DrSutherland/no-OS
/***************************************************************************//**
 * @brief Sets the AD9643 test mode for DCO delay calibration
 *
 * @param chan_mask - Selects the internal ADC the command is applied to.
 * @param mode - ADC test mode
 *
 * @return Negative error code or 0 in case of success.
*******************************************************************************/
int32_t ad9643_testmode_set(uint32_t chan_mask, uint32_t mode)
{
	int32_t ret = 0;

	switch (mode)
	{
	case AD9643_TEST_MODE_PN23_SEQ:
	case AD9643_TEST_MODE_PN9_SEQ:
	case AD9643_TEST_MODE_ALTERNATING_CHECKERBOARD:
        ADC_Core_Write(ADC_CORE_ADC_CTRL,0);
		ret = ad9643_write(AD9643_REG_OUTPUT_MODE,
			        	  (AD9643_OUTPUT_MODE_DEF | AD9643_OUTPUT_MODE_TWOS_COMPLEMENT) &
			        	  ~AD9643_OUTPUT_MODE_TWOS_COMPLEMENT);
		break;
	default:
        ADC_Core_Write(ADC_CORE_ADC_CTRL,ADC_CORE_SIGNEXTEND);
		ret = ad9643_write(AD9643_REG_OUTPUT_MODE, (AD9643_OUTPUT_MODE_DEF |
                                           	   	 AD9643_OUTPUT_MODE_TWOS_COMPLEMENT));
	};
	if(ret < 0)
		return ret;

	ret = ad9643_write(AD9643_REG_CHANNEL_IDX, chan_mask);
	if(ret < 0)
		return ret;

	ret = ad9643_write(AD9643_REG_TEST_MODE, mode);
	if(ret < 0)
		return ret;

	ret = ad9643_write(AD9643_REG_CHANNEL_IDX, AD9643_CHANNEL_IDX_ADC_AB);
	if(ret < 0)
		return ret;

	ret = ad9643_write(AD9643_REG_TRANSFER, AD9643_TRANSFER_EN);
	if(ret < 0)
		return ret;

	return ret;
}
예제 #4
0
파일: AD9643.c 프로젝트: DrSutherland/no-OS
/***************************************************************************//**
 * @brief Initializes the AD9643. 
 *
 * @return Negative error code or 0 in case of success.
*******************************************************************************/
int32_t ad9643_setup()
{
    int32_t ret = 0;
	
	ad9643_reset();
	ad9643_write(AD9643_REG_CLK_PHASE_CTRL, AD9643_CLK_PHASE_CTRL_EVEN_ODD_MODE_EN);
    ADC_Core_Write(ADC_CORE_ADC_CTRL,ADC_CORE_SIGNEXTEND | ADC_CORE_SCALE_OFFSET_EN);
    ADC_Core_Write(ADC_CORE_CA_OFFS_SCALE,ADC_CORE_OFFSET(0) | ADC_CORE_SCALE(0x8000));
    ADC_Core_Write(ADC_CORE_CB_OFFS_SCALE,ADC_CORE_OFFSET(0) | ADC_CORE_SCALE(0x8000));
	ad9643_write(AD9643_REG_OUTPUT_MODE, AD9643_OUTPUT_MODE_DEF | AD9643_OUTPUT_MODE_TWOS_COMPLEMENT);
	ad9643_write(AD9643_REG_TEST_MODE, AD9643_TEST_MODE_OFF);
	ad9643_write(AD9643_REG_TRANSFER, AD9643_TRANSFER_EN);

	ret = ad9643_dco_calibrate_2c();
	if(ret < 0)
	{
		ad9643_dco_clock_invert(1);
		ret = ad9643_dco_calibrate_2c();
	}

    ADC_Core_Write(ADC_CORE_DMA_CHAN_SEL,0x02);

	return ret < 0 ? -1 : 0;
}
예제 #5
0
파일: xcomm.c 프로젝트: DrSutherland/no-OS
/**************************************************************************//**
* @brief Calibrates the ADC DCO clock delay 
* 
* @return If success, returns DCO clock delay code
*		  if error,return -1
******************************************************************************/
int32_t XCOMM_CalibrateAdcDco(void)
{
	int32_t ret;

	ADC_Core_Write(ADC_CORE_DMA_CHAN_SEL,0x00);

	ad9643_dco_clock_invert(0);
	ret = ad9643_dco_calibrate_2c();

	if(ret<0)
	{
		ad9643_dco_clock_invert(1);
		ret = ad9643_dco_calibrate_2c();
                if (!(ret<0))
                {
                    ret |= 0x0100;
                }

	}

	ADC_Core_Write(ADC_CORE_DMA_CHAN_SEL,0x02);

	return ret;
}
예제 #6
0
파일: AD9643.c 프로젝트: DrSutherland/no-OS
/***************************************************************************//**
 * @brief Calibrates the DCO clock delay
 *
 * @return Negative error code or DCO clock delay code in case of success.
*******************************************************************************/
int32_t ad9643_dco_calibrate_2c()
{
	int32_t dco, ret, cnt, start, max_start, max_cnt;
	uint32_t stat;
	uint32_t regVal;
	uint8_t err_field[33];

	ad9643_testmode_set(0x2, AD9643_TEST_MODE_PN23_SEQ);
	ad9643_testmode_set(0x1, AD9643_TEST_MODE_PN9_SEQ);

    ADC_Core_Write(ADC_CORE_PN_ERR_CTRL, ADC_CORE_PN23_1_EN | ADC_CORE_PN9_0_EN);

	for(dco = 0; dco <= 32; dco++)
    {
		ret = -1;
		ad9643_write(AD9643_REG_DCO_OUTPUT_DELAY, dco > 0 ? ((dco - 1) | 0x80) : 0);
		ad9643_write(AD9643_REG_TRANSFER, AD9643_TRANSFER_EN);
        ad9643_read(AD9643_REG_DCO_OUTPUT_DELAY);

        ADC_Core_Write(ADC_CORE_ADC_STAT, ADC_CORE_ADC_STAT_MASK);

		delay_us(1000);

        ADC_Core_Read(ADC_CORE_ADC_STAT, &stat);

        if(!( stat & 0x3c))
        {
                ret = 0;
		}

		err_field[dco] = !!ret;
	}

	ret = -1;
	for(dco = 0, cnt = 0, max_cnt = 0, start = -1, max_start = 0;
		dco <= 32; dco++) 
    {
		if (err_field[dco] == 0) 
        {
			if (start == -1)
				start = dco;
			cnt++;
			ret = 0;
		} 
        else 
        {
			if (cnt > max_cnt) 
            {
				max_cnt = cnt;
				max_start = start;
			}
			start = -1;
			cnt = 0;
		}
	}

	if (cnt > max_cnt) 
    {
		max_cnt = cnt;
		max_start = start;
	}

	dco = max_start + (max_cnt / 2);
	regVal = dco > 0 ? ((dco - 1) | 0x80) : 0;

	ad9643_testmode_set(0x3, AD9643_TEST_MODE_OFF);
	ad9643_write(AD9643_REG_DCO_OUTPUT_DELAY,regVal);
	ad9643_write(AD9643_REG_TRANSFER, AD9643_TRANSFER_EN);

	return ret < 0 ? -1 : (regVal & 0x1F);
}