609 lines
16 KiB
C
609 lines
16 KiB
C
/******************************************************************************
|
|
* drivers/wireless/spirit/lib/spirit_calibration.c
|
|
*
|
|
* Copyright(c) 2015 STMicroelectronics
|
|
* Author: VMA division - AMS
|
|
* Version 3.2.2 08-July-2015
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of STMicroelectronics nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
* Included Files
|
|
******************************************************************************/
|
|
|
|
#include <stdbool.h>
|
|
#include <assert.h>
|
|
|
|
#include "spirit_calibration.h"
|
|
#include "spirit_spi.h"
|
|
|
|
/******************************************************************************
|
|
* Public Functions
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_enable_rco
|
|
*
|
|
* Description:
|
|
* Enables or Disables the RCO calibration.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for RCO calibration. This parameter can be
|
|
* S_ENABLE or S_DISABLE.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_calib_enable_rco(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Reads the register value */
|
|
|
|
ret = spirit_reg_read(spirit, PROTOCOL2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Build new value for the register */
|
|
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= PROTOCOL2_RCO_CALIBRATION_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= ~PROTOCOL2_RCO_CALIBRATION_MASK;
|
|
}
|
|
|
|
/* Write register to enable or disable the RCO calibration */
|
|
|
|
ret = spirit_reg_write(spirit, PROTOCOL2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_enable_vco
|
|
*
|
|
* Description:
|
|
* Enables or Disables the VCO calibration.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for VCO calibration. This parameter can be
|
|
* S_ENABLE or S_DISABLE.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_calib_enable_vco(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Reads the register value */
|
|
|
|
ret = spirit_reg_read(spirit, PROTOCOL2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Build new value for the register */
|
|
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= PROTOCOL2_VCO_CALIBRATION_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= ~PROTOCOL2_VCO_CALIBRATION_MASK;
|
|
}
|
|
|
|
/* Writes register to enable or disable the VCO calibration */
|
|
|
|
ret = spirit_reg_write(spirit, PROTOCOL2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calibration_set_rcocal
|
|
*
|
|
* Description:
|
|
* Sets the RCO calibration words.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* rwt - RWT word for RCO calibration.
|
|
* rfb - RFB word for RCO calibration.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_calibration_set_rcocal(FAR struct spirit_library_s *spirit,
|
|
uint8_t rwt, uint8_t rfb)
|
|
{
|
|
uint8_t regval[2];
|
|
int ret;
|
|
|
|
/* Build the value of RWT and the MSbits of the RFB word */
|
|
|
|
regval[0] = (rwt << 4) | (rfb >> 1);
|
|
|
|
/* Reads the register value to update the LSbit of RFB */
|
|
|
|
ret = spirit_reg_read(spirit, RCO_VCO_CALIBR_IN1_BASE, ®val[1], 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Build new value for the register */
|
|
|
|
regval[1] = (regval[1] & 0x7f) | (rfb << 7);
|
|
|
|
/* Write the new value for RCO calibration words */
|
|
|
|
ret = spirit_reg_write(spirit, RCO_VCO_CALIBR_IN2_BASE, regval, 2);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calibration_get_rcocal
|
|
*
|
|
* Description:
|
|
* Returns the RCO calibration words.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* rwt - Pointer to the variable in which the RWT word has to be
|
|
* stored.
|
|
* rfb - Pointer to the variable in which the RFB word has to be
|
|
* stored.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_calibration_get_rcocal(FAR struct spirit_library_s *spirit,
|
|
FAR uint8_t *rwt, FAR uint8_t *rfb)
|
|
{
|
|
uint8_t regval[2];
|
|
int ret;
|
|
|
|
/* Read the registers values */
|
|
|
|
ret = spirit_reg_read(spirit, RCO_VCO_CALIBR_OUT1_BASE, regval, 2);
|
|
if (ret >= 0)
|
|
{
|
|
/* Build the RWT value */
|
|
|
|
(*rwt) = regval[0] >> 4;
|
|
|
|
/* Build the RFB value */
|
|
|
|
(*rfb) = (regval[0] & 0x0f) << 1 | (regval[1] >> 7);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_get_vcocal
|
|
*
|
|
* Description:
|
|
* Returns the VCO calibration data from internal VCO calibrator.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* VCO calibration data byte.
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_calib_get_vcocal(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Reads the register value */
|
|
|
|
spirit_reg_read(spirit, RCO_VCO_CALIBR_OUT0_BASE, ®val, 1);
|
|
|
|
/* Build and return the VCO calibration data value */
|
|
|
|
return (regval & 0x7f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_set_vcotxcal
|
|
*
|
|
* Description:
|
|
* Sets the VCO calibration data to be used in TX mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* caldata - Calibration data word to be set.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_calib_set_vcotxcal(FAR struct spirit_library_s *spirit,
|
|
uint8_t caldata)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Reads the register value */
|
|
|
|
ret = spirit_reg_read(spirit, RCO_VCO_CALIBR_IN1_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Build the value to be written */
|
|
|
|
regval &= 0x80;
|
|
regval |= caldata;
|
|
|
|
/* Writes the new value of calibration data in TX */
|
|
|
|
ret = spirit_reg_write(spirit, RCO_VCO_CALIBR_IN1_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_get_vcotxcal
|
|
*
|
|
* Description:
|
|
* Returns the actual VCO calibration data used in TX mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* VCO calibration data used in TX mode
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_calib_get_vcotxcal(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Reads the register containing the calibration data word used in TX mode */
|
|
|
|
spirit_reg_read(spirit, RCO_VCO_CALIBR_IN1_BASE, ®val, 1);
|
|
|
|
/* Mask the VCO_CALIBR_TX field and returns the value */
|
|
|
|
return (regval & 0x7f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_set_vcorxcal
|
|
*
|
|
* Description:
|
|
* Sets the VCO calibration data to be used in RX mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* caldata - Calibration data word to be set.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_calib_set_vcorxcal(FAR struct spirit_library_s *spirit,
|
|
uint8_t caldata)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Reads the register value */
|
|
|
|
ret = spirit_reg_read(spirit, RCO_VCO_CALIBR_IN0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Build the value to be written */
|
|
|
|
regval &= 0x80;
|
|
regval |= caldata;
|
|
|
|
/* Write the new value of calibration data in RX */
|
|
|
|
ret = spirit_reg_write(spirit, RCO_VCO_CALIBR_IN0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_get_vcorxcal
|
|
*
|
|
* Description:
|
|
* Returns the actual VCO calibration data used in RX mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Calibration data word used in RX mode.
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_calib_get_vcorxcal(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Reads the register containing the calibration data word used in TX mode */
|
|
|
|
spirit_reg_read(spirit, RCO_VCO_CALIBR_IN0_BASE, ®val, 1);
|
|
|
|
/* Mask the VCO_CALIBR_RX field and returns the value */
|
|
|
|
return (regval & 0x7f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calibration_set_vcowin
|
|
*
|
|
* Description:
|
|
* Sets the VCO calibration window.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* refword - Value of REFWORD corresponding to the Ref_period according to
|
|
* the formula:
|
|
*
|
|
* CALIBRATION_WIN = 11*Ref_period/fxo.
|
|
*
|
|
* This parameter can be a value of enum spirit_vcowin_e.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_calibration_set_vcowin(FAR struct spirit_library_s *spirit,
|
|
enum spirit_vcowin_e refword)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_VCO_WIN(refword));
|
|
|
|
/* Reads the register value */
|
|
|
|
ret = spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Build the values to be written */
|
|
|
|
regval &= 0xfc;
|
|
regval |= refword;
|
|
|
|
/* Write the new value of VCO calibration window */
|
|
|
|
ret = spirit_reg_write(spirit, SYNTH_CONFIG1_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calibration_get_vcowin
|
|
*
|
|
* Description:
|
|
* Returns the VCO calibration window.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Value of REFWORD corresponding to the Ref_period according to the
|
|
* formula:
|
|
*
|
|
* CALIBRATION_WIN = 11*Ref_period/fxo.
|
|
*
|
|
* This parameter can be a value of enum spirit_vcowin_e.
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_vcowin_e
|
|
spirit_calibration_get_vcowin(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval1;
|
|
uint8_t regval2;
|
|
enum spirit_vcowin_e refword;
|
|
|
|
/* Reads the register containing the REFWORD value */
|
|
|
|
spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val1, 1);
|
|
|
|
/* Reads the Xtal configuration */
|
|
|
|
spirit_reg_read(spirit, ANA_FUNC_CONF0_BASE, ®val2, 1);
|
|
|
|
/* Mask the REFWORD field */
|
|
|
|
regval1 &= 0x03;
|
|
|
|
/* Mask the 24_26_MHz_SELECT field */
|
|
|
|
regval2 = ((regval2 & 0x40) >> 6);
|
|
|
|
/* In case of 26 MHz crystal */
|
|
|
|
if (regval2 != 0)
|
|
{
|
|
switch (regval1)
|
|
{
|
|
case 0:
|
|
refword = CALIB_TIME_6_77_US_26MHZ;
|
|
break;
|
|
|
|
case 1:
|
|
refword = CALIB_TIME_13_54_US_26MHZ;
|
|
break;
|
|
|
|
case 2:
|
|
refword = CALIB_TIME_27_08_US_26MHZ;
|
|
break;
|
|
|
|
case 3:
|
|
refword = CALIB_TIME_54_15_US_26MHZ;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* In case of 24 MHz crystal */
|
|
|
|
else
|
|
{
|
|
switch (regval1)
|
|
{
|
|
case 0:
|
|
refword = CALIB_TIME_7_33_US_24MHZ;
|
|
break;
|
|
|
|
case 1:
|
|
refword = CALIB_TIME_14_67_US_24MHZ;
|
|
break;
|
|
|
|
case 2:
|
|
refword = CALIB_TIME_29_33_US_24MHZ;
|
|
break;
|
|
|
|
case 3:
|
|
refword = CALIB_TIME_58_67_US_24MHZ;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return refword;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_select_vco
|
|
*
|
|
* Description:
|
|
* Selects a VCO.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* vco - Can be VCO_H or VCO_L according to which VCO select.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_calib_select_vco(FAR struct spirit_library_s *spirit,
|
|
enum spirit_vcoselect_e vco)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_VCO_SEL(vco));
|
|
|
|
ret = spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
regval &= 0xf9;
|
|
|
|
if (vco == VCO_H)
|
|
{
|
|
regval |= 0x02;
|
|
}
|
|
else
|
|
{
|
|
regval |= 0x04;
|
|
}
|
|
|
|
ret = spirit_reg_write(spirit, SYNTH_CONFIG1_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_calib_get_vco
|
|
*
|
|
* Description:
|
|
* Returns the VCO selected.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* VCO_H or VCO_L according to which VCO selected.
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_vcoselect_e spirit_calib_get_vco(
|
|
FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1);
|
|
|
|
regval = (regval >> 1) & 0x3;
|
|
if (regval == 0x01)
|
|
{
|
|
return VCO_H;
|
|
}
|
|
else
|
|
{
|
|
return VCO_L;
|
|
}
|
|
}
|