diff --git a/drivers/wireless/spirit/drivers/spirit_netdev.c b/drivers/wireless/spirit/drivers/spirit_netdev.c index 03f7820888..8b9f40b309 100644 --- a/drivers/wireless/spirit/drivers/spirit_netdev.c +++ b/drivers/wireless/spirit/drivers/spirit_netdev.c @@ -512,7 +512,7 @@ static int spirit_transmit(FAR struct spirit_driver_s *priv) goto errout_with_iob; } - /* Sets the length of the packet to send */ + /* Make sure that the TX linear FIFO is completely empty */ ret = spirit_command(spirit, COMMAND_FLUSHTXFIFO); if (ret < 0) @@ -520,6 +520,8 @@ static int spirit_transmit(FAR struct spirit_driver_s *priv) goto errout_with_iob; } + /* Sets the length of the packet to send */ + ret = spirit_pktbasic_set_payloadlen(spirit, iob->io_len); if (ret < 0) { @@ -555,14 +557,16 @@ static int spirit_transmit(FAR struct spirit_driver_s *priv) goto errout_with_iob; } - /* Puts the SPIRIT1 in TX state */ + /* Put the SPIRIT1 into TX state. This starts the transmission */ - ret = spirit_command(spirit, COMMAND_TX); /* Starts transmission */ + ret = spirit_command(spirit, COMMAND_TX); if (ret < 0) { goto errout_with_iob; } + /* Wait until we have successfully entered the TX state */ + ret = spirit_waitstatus(spirit, MC_STATE_TX, 5); if (ret < 0) { diff --git a/drivers/wireless/spirit/include/spirit_radio.h b/drivers/wireless/spirit/include/spirit_radio.h index dbcfa412e4..b5981b31ef 100644 --- a/drivers/wireless/spirit/include/spirit_radio.h +++ b/drivers/wireless/spirit/include/spirit_radio.h @@ -390,6 +390,27 @@ struct radio_init_s int spirit_radio_initialize(FAR struct spirit_library_s *spirit, FAR const struct radio_init_s *radioinit); +/****************************************************************************** + * Name: spirit_radio_get_setup + * + * Description: + * Returns the SPIRIT analog and digital radio structure according to the + * registers value. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * radioinit pointer to a struct radio_init_s that + * contains the configuration information for the analog radio part of SPIRIT. + * + * Returned Value: + * Zero (OK) returned on success; a negated errno value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_get_setup(FAR struct spirit_library_s *spirit, + FAR struct radio_init_s *radioinit); + /****************************************************************************** * Name: spirit_radio_set_xtalflag * @@ -528,6 +549,41 @@ int spirit_radio_set_band(FAR struct spirit_library_s *spirit, enum spirit_bandselect_e spirit_radio_get_band(FAR struct spirit_library_s *spirit); +/****************************************************************************** + * Name: spirit_radio_get_channel + * + * Description: + * Returns the actual channel number. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Actual channel number. + * + ******************************************************************************/ + +uint8_t spirit_radio_get_channel(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_set_foffset_ppm + * + * Description: + * Sets the FC OFFSET register starting from xtal ppm value. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * xtaloffset - The xtal offset expressed in ppm. + * + * Returned Value: + * Zero (OK) returned on success; a negated errno value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_foffset_ppm(FAR struct spirit_library_s *spirit, + int16_t xtaloffset); + /****************************************************************************** * Name: spirit_radio_set_chspace * @@ -588,20 +644,23 @@ int spirit_radio_set_channel(FAR struct spirit_library_s *spirit, uint8_t chnum); /****************************************************************************** - * Name: spirit_radio_get_channel + * Name: spirit_radio_set_foffset_hz * * Description: - * Returns the actual channel number. + * Sets the FC OFFSET register starting from frequency offset expressed in Hz. * * Input Parameters: - * spirit - Reference to a Spirit library state structure instance + * spirit - Reference to a Spirit library state structure instance + * foffset - Frequency offset expressed in Hz as signed word. * * Returned Value: - * Actual channel number. + * Zero (OK) returned on success; a negated errno value is returned on any + * failure. * ******************************************************************************/ -uint8_t spirit_radio_get_channel(FAR struct spirit_library_s *spirit); +int spirit_radio_set_foffset_hz(FAR struct spirit_library_s *spirit, + int32_t foffset); /****************************************************************************** * Name: spirit_radio_get_foffset @@ -675,6 +734,22 @@ void spirit_radio_enable_wavco_calibration(FAR struct spirit_library_s *spirit, uint32_t spirit_radio_get_basefrequency(FAR struct spirit_library_s *spirit); +/****************************************************************************** + * Name: spirit_radio_get_centerfreq + * + * Description: + * Returns the actual channel center frequency. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Actual channel center frequency expressed in Hz. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_centerfreq(FAR struct spirit_library_s *spirit); + /****************************************************************************** * Name: spirit_radio_convert_datarate * @@ -697,6 +772,32 @@ int spirit_radio_convert_datarate(FAR struct spirit_library_s *spirit, uint32_t datarate, FAR uint8_t *pcm, FAR uint8_t *pce); +/****************************************************************************** + * Name: spirit_radio_convert_chbandwidth + * + * Description: + * Returns the mantissa and exponent for a given bandwidth. Even if it is + * possible to pass as parameter any value in the below mentioned range, the + * API will search the closer value according to a fixed table of channel + * bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet, + * returning the corresponding mantissa and exponent value. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * bandwidth - bandwidth expressed in Hz. This parameter ranging between + * 1100 and 800100. + * pcm - pointer to the returned mantissa value. + * pce - pointer to the returned exponent value. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_convert_chbandwidth(FAR struct spirit_library_s *spirit, + uint32_t bandwidth, FAR uint8_t *pcm, + FAR uint8_t *pce); + /****************************************************************************** * Name: spirit_radio_convert_freqdev * @@ -722,33 +823,212 @@ int spirit_radio_convert_freqdev(FAR struct spirit_library_s *spirit, FAR uint8_t *pce); /****************************************************************************** - * Name: + * Name: spirit_radio_set_datarate * * Description: - * Returns the mantissa and exponent for a given bandwidth. Even if it is - * possible to pass as parameter any value in the below mentioned range, the - * API will search the closer value according to a fixed table of channel - * bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet, - * returning the corresponding mantissa and exponent value. + * Sets the datarate. * * Input Parameters: - * spirit - Reference to a Spirit library state structure instance - * bandwidth - bandwidth expressed in Hz. This parameter ranging between - * 1100 and 800100. - * pcm - pointer to the returned mantissa value. - * pce - pointer to the returned exponent value. + * spirit - Reference to a Spirit library state structure instance + * datarate - Datarate expressed in bps. This value must be in the range + * [100 500000]. * * Returned Value: - * Error code: 0=no error, <0=error during calibration of VCO. + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. * ******************************************************************************/ -int spirit_radio_convert_chbandwidth(FAR struct spirit_library_s *spirit, - uint32_t bandwidth, FAR uint8_t *pcm, - FAR uint8_t *pce); +int spirit_radio_set_datarate(FAR struct spirit_library_s *spirit, + uint32_t datarate); /****************************************************************************** - * Name: spirit_radio_dbm2reg + * Name: spirit_radio_get_datarate + * + * Description: + * Returns the datarate. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Settled datarate expressed in bps. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_datarate(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_set_freqdev + * + * Description: + * Sets the frequency deviation. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fdev - Frequency deviation expressed in Hz. Be sure that this value + * is in the correct range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_freqdev(FAR struct spirit_library_s *spirit, + uint32_t fdev); + +/****************************************************************************** + * Name: spirit_radio_get_freqdev + * + * Description: + * Returns the frequency deviation. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Frequency deviation value expressed in Hz. + * This value will be in the range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_freqdev(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_set_chfilterbw + * + * Description: + * Sets the channel filter bandwidth. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * bandwidth - Channel filter bandwidth expressed in Hz. This parameter + * must be in the range [1100 800100]. The API will search the + * closest value according to a fixed table of channel bandwidth + * values, as defined in the datasheet. To verify the settled + * channel bandwidth it is possible to use the + * spirit_radio_get_chfilterbw() API. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_chfilterbw(FAR struct spirit_library_s *spirit, + uint32_t bandwidth); + +/****************************************************************************** + * Name: spirit_radio_get_chfilterbw + * + * Description: + * Returns the channel filter bandwidth. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Channel filter bandwidth expressed in Hz. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_chfilterbw(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_set_modulation + * + * Description: + * Sets the modulation type. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * modulation - Modulation to set. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_modulation(FAR struct spirit_library_s *spirit, + enum modulation_select_e modulation); + +/****************************************************************************** + * Name: spirit_radio_get_modulation + * + * Description: + * Returns the modulation type used. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Settled modulation type. + * + ******************************************************************************/ + +enum modulation_select_e + spirit_radio_get_modulation(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_enable_cwtxmode + * + * Description: + * Enables or Disables the Continuous Wave transmit mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for power ramping. This parameter can be: S_ENABLE + * or S_DISABLE . + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_enable_cwtxmode(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_radio_set_ookpeackdecay + * + * Description: + * Sets the OOK Peak Decay. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * ookdelay - Peak decay control for OOK. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_ookpeackdecay(FAR struct spirit_library_s *spirit, + enum spirit_ookpeakdelay_e ookdelay); + +/****************************************************************************** + * Name: spirit_radio_get_ookpeackdecay + * + * Description: + * Returns the OOK Peak Decay. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Ook peak decay value. + * + ******************************************************************************/ + +enum spirit_ookpeakdelay_e + spirit_radio_get_ookpeackdecay(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_convert_power2reg * * Description: * Returns the PA register value that corresponds to the passed dBm power. @@ -766,8 +1046,89 @@ int spirit_radio_convert_chbandwidth(FAR struct spirit_library_s *spirit, * ******************************************************************************/ -uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, - uint32_t fbase, float powerdbm); +uint8_t spirit_radio_convert_power2reg(FAR struct spirit_library_s *spirit, + uint32_t fbase, float powerdbm); + +/****************************************************************************** + * Name: spirit_radio_convert_reg2power + * + * Description: + * Returns the dBm power that corresponds to the value of PA register. + * + * NOTE: The power interpolation curves used by this function have been + * extracted by measurements done on the divisional evaluation boards. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fbase - Frequency base expressed in Hz. + * regval - Register value of the PA. + * + * Returned Value: + * Power in dBm as float. + * + ******************************************************************************/ + +float spirit_radio_convert_reg2power(FAR struct spirit_library_s *spirit, + uint32_t fbase, uint8_t regval); + +/****************************************************************************** + * Name: spirit_radio_config_patable + * + * Description: + * Configures the Power Amplifier Table and registers with value expressed + * in dBm. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * nlevels - Number of levels to set. This parameter must be in the range + * [0:7]. + * width - Step width expressed in terms of bit period units Tb/8. This + * parameter must be in the range [1:4]. + * load - The of the possible value of the enum type enum + * pirit_paload_capacitor_e. + * + * LOAD_0_PF No additional PA load capacitor + * LOAD_1_2_PF 1.2pF additional PA load capacitor + * LOAD_2_4_PF 2.4pF additional PA load capacitor + * LOAD_3_6_PF 3.6pF additional PA load capacitor + * + * table - Pointer to an array of PA values in dbm between + * [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dbm. The first element must + * be the lower level (PA_LEVEL[0]) value and the last element + * the higher level one (PA_LEVEL[paLevelMaxIndex]). + * + * Returned Value: + * Zero (OK) on success. A negated errno value is returned on any failure. + * + ******************************************************************************/ + +int spirit_radio_config_patable(FAR struct spirit_library_s *spirit, + uint8_t nlevels, uint8_t width, + enum spirit_paload_capacitor_e load, + FAR float *table); + +/****************************************************************************** + * Name: regaddr + * + * Description: + * Returns the Power Amplifier Table and registers, returning values in dBm. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * nlevels - Pointer to the number of levels settled. This parameter must + * be in the range [0:7]. + * table - Pointer to an array of 8 elements containing the PA value in dbm. + * The first element will be the PA_LEVEL_0 and the last element + * will be PA_LEVEL_7. Any value higher than PA_UPPER_LIMIT implies + ( no output power (output stage is in high impedance). + * + * Returned Value: + * Zero (OK) on success. A negated errno value is returned on any failure. + * + ******************************************************************************/ + +int spirit_radio_get_patable(FAR struct spirit_library_s *spirit, + FAR uint8_t *nlevels, FAR float *table); /****************************************************************************** * Name: spirit_radio_set_palevel @@ -775,8 +1136,8 @@ uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, * Description: * Sets a specific PA_LEVEL register, with a value given in dBm. * - * NOTE: This function makes use of the @ref spirit_radio_dbm2reg fcn to - * interpolate the power value. + * NOTE: This function makes use of the spirit_radio_convert_power2reg function + * to interpolate the power value. * * Input Parameters: * spirit - Reference to a Spirit library state structure instance diff --git a/drivers/wireless/spirit/lib/spirit_radio.c b/drivers/wireless/spirit/lib/spirit_radio.c index da2eaeb2e4..df4d3b4849 100644 --- a/drivers/wireless/spirit/lib/spirit_radio.c +++ b/drivers/wireless/spirit/lib/spirit_radio.c @@ -138,21 +138,6 @@ static const uint16_t g_vectn_vcofreq[16] = 5161, 5232, 5303, 5375, 5448, 5519, 5592, 5663 }; -/****************************************************************************** - * Private Functions - ******************************************************************************/ - -/****************************************************************************** - * Name: - * - * Description: - * - * Parameters: - * - * Returned Value: - * - ******************************************************************************/ - /****************************************************************************** * Public Functions ******************************************************************************/ @@ -205,7 +190,7 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit, /* Workaround for Vtune */ value = 0xa0; - ret = spirit_reg_write(spirit, 0x9F, &value, 1); + ret = spirit_reg_write(spirit, 0x9f, &value, 1); if (ret < 0) { return ret; @@ -236,7 +221,7 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit, for (i = 0; i != 0xff; i++); - /* Reads the MC_STATUS register */ + /* Read the MC_STATUS register */ ret = spirit_update_status(spirit); if (ret < 0) @@ -278,7 +263,7 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit, for (i = 0; i != 0xff; i++); - /* Reads the MC_STATUS register */ + /* Read the MC_STATUS register */ ret = spirit_update_status(spirit); if (ret < 0) @@ -492,6 +477,183 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit, return spirit_radio_set_basefrequency(spirit, radioinit->base_frequency); } +/****************************************************************************** + * Name: spirit_radio_get_setup + * + * Description: + * Returns the SPIRIT analog and digital radio structure according to the + * registers value. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * radioinit pointer to a struct radio_init_s that + * contains the configuration information for the analog radio part of SPIRIT. + * + * Returned Value: + * Zero (OK) returned on success; a negated errno value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_get_setup(FAR struct spirit_library_s *spirit, + FAR struct radio_init_s *radioinit) +{ + uint32_t synthword; + uint16_t xtaloff; + int16_t fcoffset; + uint8_t anaregs[8]; + uint8_t digregs[4]; + uint8_t refdiv; + uint8_t fdevm; + uint8_t fdeve; + uint8_t bwm; + uint8_t bwe; + uint8_t divider; + enum spirit_bandselect_e band; + int ret; + +#if 0 + /* Get the RF board version */ + + enum spirit_version_e spirit_version = spirit_general_get_version(spirit); +#endif + + /* Read the Analog Radio registers */ + + ret = spirit_reg_read(spirit, SYNT3_BASE, anaregs, 8); + if (ret < 0) + { + return ret; + } + + /* Read the Digital Radio registers */ + + ret = spirit_reg_read(spirit, MOD1_BASE, digregs, 4); + if (ret < 0) + { + return ret; + } + + /* Get the operating band masking the Band selected field */ + + if ((anaregs[3] & 0x07) == SYNT0_BS_6) + { + band = HIGH_BAND; + } + else if ((anaregs[3] & 0x07) == SYNT0_BS_12) + { + band = MIDDLE_BAND; + } + else if ((anaregs[3] & 0x07) == SYNT0_BS_16) + { + band = LOW_BAND; + } + else if ((anaregs[3] & 0x07) == SYNT0_BS_32) + { + band = VERY_LOW_BAND; + } + else + { + uint8_t regval; + + /* If it is another value, set it to a valid one in order to avoid access + * violation + */ + + regval = (anaregs[3] & 0xf8) | SYNT0_BS_6; + ret = spirit_reg_write(spirit, SYNT0_BASE, ®val, 1); + if (ret < 0) + { + return ret; + } + + band = HIGH_BAND; + } + + /* Compute the synth word */ + + synthword = ((((uint32_t)(anaregs[0] & 0x1f)) << 21) + + (((uint32_t)(anaregs[1])) << 13) + + (((uint32_t)(anaregs[2])) << 5) + + (((uint32_t)(anaregs[3])) >> 3)); + + /* Calculate the frequency base */ + + refdiv = (uint8_t)spirit_radio_get_refdiv(spirit) + 1; + radioinit->base_frequency = (uint32_t) + round(synthword * (((double)spirit->xtal_frequency) / + (FBASE_DIVIDER * refdiv * g_vectc_bhalf[band]))); + + /* Calculate the Offset Factor */ + + xtaloff = (((uint16_t)anaregs[6] << 8) | (uint16_t)anaregs[7]); + + /* If a negative number then convert the 12 bit 2-complement in a 16 bit + * number + */ + + if ((xtaloff & 0x0800) != 0) + { + xtaloff = xtaloff | 0xf000; + } + else + { + xtaloff = xtaloff & 0x0fff; + } + + fcoffset = (int16_t)xtaloff; + + /* Calculate the frequency offset in ppm */ + + radioinit->xtal_offset_ppm = (int16_t) + ((uint32_t)fcoffset * spirit->xtal_frequency * PPM_FACTOR) / + ((uint32_t)FBASE_DIVIDER * radioinit->base_frequency); + + /* Channel space */ + + radioinit->chspace = anaregs[4] * (spirit->xtal_frequency >> 15); + + /* Channel number */ + + radioinit->chnum = spirit_radio_get_channel(spirit); + + /* Modulation select */ + + radioinit->modselect = (enum modulation_select_e)(digregs[1] & 0x70); + + /* Get the frequency deviation for mantissa and exponent */ + + fdevm = digregs[2] & 0x07; + fdeve = (digregs[2] & 0xf0) >> 4; + + /* Get the channel filter register for mantissa and exponent */ + + bwm = (digregs[3] & 0xf0) >> 4; + bwe = digregs[3] & 0x0f; + + divider = spirit_radio_isenabled_digdivider(spirit); + + /* Calculate the datarate */ + + radioinit->datarate = + ((spirit->xtal_frequency >> (5 + divider)) * + (256 + digregs[0])) >> (23 - (digregs[1] & 0x0f)); + + /* Calculates the frequency deviation */ + + radioinit->freqdev = (uint32_t) + ((float)spirit->xtal_frequency / (((uint32_t) 1) << 18) * + (uint32_t)((8.0 + fdevm) / 2 * (1 << fdeve))); + + /* Get the channel filter bandwidth from the look-up table and return it */ + + radioinit->bandwidth = (uint32_t) + (100.0 * g_vectn_bandwidth[bwm + (bwe * 9)] * + ((spirit->xtal_frequency >> divider) / 26e6)); + + return OK; +} + /****************************************************************************** * Name: spirit_radio_set_xtalflag * @@ -500,9 +662,9 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit, * * Input Parameters: * spirit - Reference to a Spirit library state structure instance - * xtalflag one of the possible value of the enum type xtal_flag_e. - * XTAL_FLAG_24_MHz: in case of 24 MHz crystal - * XTAL_FLAG_26_MHz: in case of 26 MHz crystal + * xtalflag - One of the possible value of the enum type xtal_flag_e. + * XTAL_FLAG_24_MHz: in case of 24 MHz crystal + * XTAL_FLAG_26_MHz: in case of 26 MHz crystal * * Returned Value: * Error code: 0=no error, <0=error during calibration of VCO. @@ -519,7 +681,7 @@ int spirit_radio_set_xtalflag(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_XTAL_FLAG(xtalflag)); - /* Reads the ANA_FUNC_CONF_0 register */ + /* Read the ANA_FUNC_CONF_0 register */ ret = spirit_reg_read(spirit, ANA_FUNC_CONF0_BASE, ®val, 1); if (ret >= 0) @@ -559,7 +721,7 @@ enum xtal_flag_e spirit_radio_get_xtalflag(FAR struct spirit_library_s *spirit) { uint8_t regval; - /* Reads the Xtal configuration in the ANA_FUNC_CONF_0 register and return + /* Read the Xtal configuration in the ANA_FUNC_CONF_0 register and return * the value. */ @@ -667,7 +829,7 @@ uint32_t spirit_radio_get_synthword(FAR struct spirit_library_s *spirit) { uint8_t regvalues[4]; - /* Reads the SYNTH registers, build the synth word and return it */ + /* Read the SYNTH registers, build the synth word and return it */ (void)spirit_reg_read(spirit, SYNT3_BASE, regvalues, 4); return ((((uint32_t) (regvalues[0] & 0x1f)) << 21) + @@ -698,7 +860,7 @@ int spirit_radio_set_synthword(FAR struct spirit_library_s *spirit, uint8_t synt0; int ret; - /* Reads the SYNT0 register */ + /* Read the SYNT0 register */ ret = spirit_reg_read(spirit, SYNT0_BASE, &synt0, 1); if (ret < 0) @@ -752,7 +914,7 @@ int spirit_radio_set_band(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_BAND_SELECTED(band)); - /* Reads the SYNT0 register */ + /* Read the SYNT0 register */ ret = spirit_reg_read(spirit, SYNT0_BASE, ®val, 1); if (ret >= 0) @@ -794,7 +956,7 @@ enum spirit_bandselect_e { uint8_t regval; - /* Reads the SYNT0 register */ + /* Read the SYNT0 register */ (void)spirit_reg_read(spirit, SYNT0_BASE, ®val, 1); @@ -818,6 +980,54 @@ enum spirit_bandselect_e } } +/****************************************************************************** + * Name: spirit_radio_set_channel + * + * Description: + * Sets the channel number. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * chnum the channel number. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. + * + ******************************************************************************/ + +int spirit_radio_set_channel(FAR struct spirit_library_s *spirit, + uint8_t chnum) +{ + /* Write the CHNUM register */ + + return spirit_reg_write(spirit, CHNUM_BASE, &chnum, 1); +} + +/****************************************************************************** + * Name: spirit_radio_get_channel + * + * Description: + * Returns the actual channel number. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Actual channel number. + * + ******************************************************************************/ + +uint8_t spirit_radio_get_channel(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Read the CHNUM register and return the value */ + + (void)spirit_reg_read(spirit, CHNUM_BASE, ®val, 1); + return regval; +} + /****************************************************************************** * Name: spirit_radio_set_chspace * @@ -871,7 +1081,7 @@ uint32_t spirit_radio_get_chspace(FAR struct spirit_library_s *spirit) { uint8_t factor; - /* Reads the CHSPACE register, calculate the channel space and return it */ + /* Read the CHSPACE register, calculate the channel space and return it */ (void)spirit_reg_read(spirit, CHSPACE_BASE, &factor, 1); @@ -881,51 +1091,110 @@ uint32_t spirit_radio_get_chspace(FAR struct spirit_library_s *spirit) } /****************************************************************************** - * Name: spirit_radio_set_channel + * Name: spirit_radio_set_foffset_ppm * * Description: - * Sets the channel number. + * Sets the FC OFFSET register starting from xtal ppm value. * * Input Parameters: - * spirit - Reference to a Spirit library state structure instance - * chnum the channel number. + * spirit - Reference to a Spirit library state structure instance + * xtaloffset - The xtal offset expressed in ppm. * * Returned Value: - * Zero (OK) is returned on success. A negated errno value is returned on - * any failure. + * Zero (OK) returned on success; a negated errno value is returned on any + * failure. * ******************************************************************************/ -int spirit_radio_set_channel(FAR struct spirit_library_s *spirit, - uint8_t chnum) +int spirit_radio_set_foffset_ppm(FAR struct spirit_library_s *spirit, + int16_t xtaloffset) { - /* Writes the CHNUM register */ + enum spirit_bandselect_e band; + uint32_t synthword; + uint32_t fbase; + int32_t offset; + int16_t fcoffset; + uint8_t refdiv; + uint8_t tmp[2]; - return spirit_reg_write(spirit, CHNUM_BASE, &chnum, 1); + /* Get the synth word */ + + synthword = spirit_radio_get_synthword(spirit); + + /* Get the operating band */ + + band = spirit_radio_get_band(spirit); + + /* Calculate the frequency base */ + + refdiv = (uint8_t)spirit_radio_get_refdiv(spirit) + 1; + fbase = synthword * (spirit->xtal_frequency / + (g_vectc_bhalf[band] * refdiv) / + FBASE_DIVIDER); + + /* Calculate the offset respect to RF frequency and according to xtal_ppm + * parameter */ + + offset = (int32_t)(((float)xtaloffset * fbase) / PPM_FACTOR); + + /* Check the Offset is in the correct range */ + + DEBUGASSERT(IS_FREQUENCY_OFFSET(offset, spirit->xtal_frequency)); + + /* Calculate the FC_OFFSET value to write in the corresponding register */ + + fcoffset = (int16_t)(((float)offset * FBASE_DIVIDER) / + spirit->xtal_frequency); + + /* Build the array related to the FC_OFFSET_1 and FC_OFFSET_0 register */ + + tmp[0] = (uint8_t)((((uint16_t) fcoffset) >> 8) & 0x0F); + tmp[1] = (uint8_t)fcoffset; + + /* Write the FC_OFFSET registers */ + + return spirit_reg_write(spirit, FC_OFFSET1_BASE, tmp, 2); } /****************************************************************************** - * Name: spirit_radio_get_channel + * Name: spirit_radio_set_foffset_hz * * Description: - * Returns the actual channel number. + * Sets the FC OFFSET register starting from frequency offset expressed in Hz. * * Input Parameters: - * spirit - Reference to a Spirit library state structure instance + * spirit - Reference to a Spirit library state structure instance + * foffset - Frequency offset expressed in Hz as signed word. * * Returned Value: - * Actual channel number. + * Zero (OK) returned on success; a negated errno value is returned on any + * failure. * ******************************************************************************/ -uint8_t spirit_radio_get_channel(FAR struct spirit_library_s *spirit) +int spirit_radio_set_foffset_hz(FAR struct spirit_library_s *spirit, + int32_t foffset) { - uint8_t regval; + uint8_t tmp[2]; + int16_t offset; - /* Reads the CHNUM register and return the value */ + /* Check that the Offset is in the correct range */ - (void)spirit_reg_read(spirit, CHNUM_BASE, ®val, 1); - return regval; + DEBUGASSERT(IS_FREQUENCY_OFFSET(foffset, spirit->xtal_frequency)); + + /* Calculates the offset value to write in the FC_OFFSET register */ + + offset = (int16_t)(((float)foffset * FBASE_DIVIDER) / + spirit->xtal_frequency); + + /* Build the array related to the FC_OFFSET_1 and FC_OFFSET_0 register */ + + tmp[0] = (uint8_t)((((uint16_t) offset) >> 8) & 0x0f); + tmp[1] = (uint8_t)offset; + + /* Write the FC_OFFSET registers */ + + return spirit_reg_write(spirit, FC_OFFSET1_BASE, tmp, 2); } /****************************************************************************** @@ -948,7 +1217,7 @@ int32_t spirit_radio_get_foffset(FAR struct spirit_library_s *spirit) int16_t fcoffset; uint8_t tmp[2]; - /* Reads the FC_OFFSET registers */ + /* Read the FC_OFFSET registers */ (void)spirit_reg_read(spirit, FC_OFFSET1_BASE, tmp, 2); @@ -1035,7 +1304,7 @@ int spirit_radio_set_basefrequency(FAR struct spirit_library_s *spirit, fc = fbase + foffset + chspace * chnum; - /* Reads the reference divider */ + /* Read the reference divider */ refdiv = (uint8_t)spirit_radio_get_refdiv(spirit) + 1; @@ -1179,6 +1448,48 @@ uint32_t spirit_radio_get_basefrequency(FAR struct spirit_library_s *spirit) g_vectc_bhalf[band]))); } +/****************************************************************************** + * Name: spirit_radio_get_centerfreq + * + * Description: + * Returns the actual channel center frequency. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Actual channel center frequency expressed in Hz. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_centerfreq(FAR struct spirit_library_s *spirit) +{ + int32_t offset; + uint8_t channel; + uint32_t fbase; + uint32_t chspace; + + /* Get the frequency base */ + + fbase = spirit_radio_get_basefrequency(spirit); + + /* Get the frequency offset */ + + offset = spirit_radio_get_foffset(spirit); + + /* Get the channel space */ + + chspace = spirit_radio_get_chspace(spirit); + + /* Get the channel number */ + + channel = spirit_radio_get_channel(spirit); + + /* Calculate the channel center frequency and return it */ + + return (uint32_t)(fbase + offset + (uint32_t) (chspace * channel)); +} + /****************************************************************************** * Name: spirit_radio_convert_datarate * @@ -1267,71 +1578,7 @@ int spirit_radio_convert_datarate(FAR struct spirit_library_s *spirit, } /****************************************************************************** - * Name: spirit_radio_convert_freqdev - * - * Description: - * Returns the mantissa and exponent, whose value used in the frequency - * deviation formula will give a frequency deviation value most closer to - * the given frequency deviation. - * - * Input Parameters: - * spirit - Reference to a Spirit library state structure instance - * fdev - Frequency deviation expressed in Hz. This parameter can be a - * value in the range [F_Xo*8/2^18, F_Xo*7680/2^18]. - * pcm - pointer to the returned mantissa value. - * pce - pointer to the returned exponent value. - * - * Returned Value: - * Error code: 0=no error, <0=error during calibration of VCO. - * - ******************************************************************************/ - -int spirit_radio_convert_freqdev(FAR struct spirit_library_s *spirit, - uint32_t fdev, FAR uint8_t *pcm, - FAR uint8_t *pce) -{ - uint32_t a; - uint32_t bp; - uint32_t b = 0; - uint8_t i; - float xtalDivtmp = (float)spirit->xtal_frequency / (((uint32_t) 1) << 18); - - /* Check the parameters */ - - DEBUGASSERT(IS_F_DEV(fdev, spirit->xtal_frequency)); - - for (i = 0; i < 10; i++) - { - a = (uint32_t) (xtalDivtmp * (uint32_t) (7.5 * (1 << i))); - if (fdev < a) - { - break; - } - } - - *pce = i; - - for (i = 0; i < 8; i++) - { - bp = b; - b = (uint32_t)(xtalDivtmp * (uint32_t)((8.0 + i) / 2 * (1 << (*pce)))); - if (fdev < b) - { - break; - } - } - - if ((fdev - bp) < (b - fdev)) - { - i--; - } - - *pcm = i; - return OK; -} - -/****************************************************************************** - * Name: + * Name: spirit_radio_convert_chbandwidth * * Description: * Returns the mantissa and exponent for a given bandwidth. Even if it is @@ -1421,7 +1668,509 @@ int spirit_radio_convert_chbandwidth(FAR struct spirit_library_s *spirit, } /****************************************************************************** - * Name: spirit_radio_dbm2reg + * Name: spirit_radio_convert_freqdev + * + * Description: + * Returns the mantissa and exponent, whose value used in the frequency + * deviation formula will give a frequency deviation value most closer to + * the given frequency deviation. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fdev - Frequency deviation expressed in Hz. This parameter can be a + * value in the range [F_Xo*8/2^18, F_Xo*7680/2^18]. + * pcm - pointer to the returned mantissa value. + * pce - pointer to the returned exponent value. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_convert_freqdev(FAR struct spirit_library_s *spirit, + uint32_t fdev, FAR uint8_t *pcm, + FAR uint8_t *pce) +{ + uint32_t a; + uint32_t bp; + uint32_t b = 0; + uint8_t i; + float xtalDivtmp = (float)spirit->xtal_frequency / (((uint32_t) 1) << 18); + + /* Check the parameters */ + + DEBUGASSERT(IS_F_DEV(fdev, spirit->xtal_frequency)); + + for (i = 0; i < 10; i++) + { + a = (uint32_t) (xtalDivtmp * (uint32_t) (7.5 * (1 << i))); + if (fdev < a) + { + break; + } + } + + *pce = i; + + for (i = 0; i < 8; i++) + { + bp = b; + b = (uint32_t)(xtalDivtmp * (uint32_t)((8.0 + i) / 2 * (1 << (*pce)))); + if (fdev < b) + { + break; + } + } + + if ((fdev - bp) < (b - fdev)) + { + i--; + } + + *pcm = i; + return OK; +} + +/****************************************************************************** + * Name: spirit_radio_set_datarate + * + * Description: + * Sets the datarate. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * datarate - Datarate expressed in bps. This value must be in the range + * [100 500000]. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_datarate(FAR struct spirit_library_s *spirit, + uint32_t datarate) +{ + uint8_t dre, regval[2]; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_DATARATE(datarate)); + + /* Calculate the datarate mantissa and exponent */ + + ret = spirit_radio_convert_datarate(spirit, datarate, ®val[0], &dre); + if (ret >= 0) + { + /* Read the MOD_O register */ + + spirit_reg_read(spirit, MOD0_BASE, ®val[1], 1); + + /* Mask the other fields and set the datarate exponent */ + + regval[1] &= 0xf0; + regval[1] |= dre; + + /* Write the Datarate registers */ + + ret = spirit_reg_write(spirit, MOD1_BASE, regval, 2); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_get_datarate + * + * Description: + * Returns the datarate. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Settled datarate expressed in bps. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_datarate(FAR struct spirit_library_s *spirit) +{ + uint8_t regval[2]; + uint8_t divider = 0; + + /* Read the datarate registers for mantissa and exponent */ + + (void)spirit_reg_read(spirit, MOD1_BASE, regval, 2); + + /* Calculates the datarate */ + + divider = (uint8_t) spirit_radio_isenabled_digdivider(spirit); + + return (((spirit->xtal_frequency >> (5 + divider)) * + (256 + regval[0])) >> (23 - (regval[1] & 0x0f))); +} + +/****************************************************************************** + * Name: spirit_radio_set_freqdev + * + * Description: + * Sets the frequency deviation. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fdev - Frequency deviation expressed in Hz. Be sure that this value + * is in the correct range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_freqdev(FAR struct spirit_library_s *spirit, + uint32_t fdev) +{ + uint8_t fdevm; + uint8_t fdeve; + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_F_DEV(fdev, spirit->xtal_frequency)); + + /* Calculates the frequency deviation mantissa and exponent */ + + ret = spirit_radio_convert_freqdev(spirit, fdev, &fdevm, &fdeve); + if (ret < 0) + { + return ret; + } + + /* Read the FDEV0 register */ + + ret = spirit_reg_read(spirit, FDEV0_BASE, ®val, 1); + if (ret >= 0) + { + /* Mask the other fields and set the frequency deviation mantissa and + * exponent + */ + + regval &= 0x08; + regval |= ((fdeve << 4) | (fdevm)); + + /* Write the Frequency deviation register */ + + ret = spirit_reg_write(spirit, FDEV0_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_get_freqdev + * + * Description: + * Returns the frequency deviation. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Frequency deviation value expressed in Hz. + * This value will be in the range [F_Xo*8/2^18, F_Xo*7680/2^18] Hz. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_freqdev(FAR struct spirit_library_s *spirit) +{ + uint8_t fdevm; + uint8_t fdeve; + uint8_t regval; + + /* Read the frequency deviation register for mantissa and exponent */ + + (void)spirit_reg_read(spirit, FDEV0_BASE, ®val, 1); + fdevm = regval & 0x07; + fdeve = (regval & 0xf0) >> 4; + + /* Calculates the frequency deviation and return it */ + + return (uint32_t)((float)spirit->xtal_frequency / (((uint32_t) 1) << 18) * + (uint32_t) ((8.0 + fdevm) / 2 * (1 << fdeve))); +} + +/****************************************************************************** + * Name: spirit_radio_set_chfilterbw + * + * Description: + * Sets the channel filter bandwidth. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * bandwidth - Channel filter bandwidth expressed in Hz. This parameter + * must be in the range [1100 800100]. The API will search the + * closest value according to a fixed table of channel bandwidth + * values, as defined in the datasheet. To verify the settled + * channel bandwidth it is possible to use the + * spirit_radio_get_chfilterbw() API. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_chfilterbw(FAR struct spirit_library_s *spirit, + uint32_t bandwidth) +{ + uint8_t bwm; + uint8_t bwe; + uint8_t regval; + int ret; + + /* Search in the channel filter bandwidth table the exponent value */ + + if (spirit_radio_isenabled_digdivider(spirit)) + { + DEBUGASSERT(IS_CH_BW(bandwidth, (spirit->xtal_frequency / 2))); + } + else + { + DEBUGASSERT(IS_CH_BW(bandwidth, (spirit->xtal_frequency))); + } + + /* Calculates the channel bandwidth mantissa and exponent */ + + ret = spirit_radio_convert_chbandwidth(spirit, bandwidth, &bwm, &bwe); + if (ret >= 0) + { + regval = (bwm << 4) | (bwe); + + /* Write the Channel filter register */ + + ret = spirit_reg_write(spirit, CHFLT_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_get_chfilterbw + * + * Description: + * Returns the channel filter bandwidth. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Channel filter bandwidth expressed in Hz. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_chfilterbw(FAR struct spirit_library_s *spirit) +{ + uint8_t regval, bwm, bwe; + + /* Read the channel filter register for mantissa and exponent */ + + (void)spirit_reg_read(spirit, CHFLT_BASE, ®val, 1); + bwm = (regval & 0xf0) >> 4; + bwe = regval & 0x0f; + + /* Read the channel filter bandwidth from the look-up table and return it */ + + return (uint32_t)(100.0 * g_vectn_bandwidth[bwm + (bwe * 9)] * + spirit->xtal_frequency / 26e6); +} + +/****************************************************************************** + * Name: spirit_radio_set_modulation + * + * Description: + * Sets the modulation type. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * modulation - Modulation to set. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_modulation(FAR struct spirit_library_s *spirit, + enum modulation_select_e modulation) +{ + uint8_t regval; + + /* Check the parameters */ + + DEBUGASSERT(IS_MODULATION_SELECTED(modulation)); + + /* Read the modulation register */ + + spirit_reg_read(spirit, MOD0_BASE, ®val, 1); + + /* Mask the other fields and set the modulation type */ + + regval &= 0x8f; + regval |= modulation; + + /* Write the modulation register */ + + return spirit_reg_write(spirit, MOD0_BASE, ®val, 1); +} + +/****************************************************************************** + * Name: spirit_radio_get_modulation + * + * Description: + * Returns the modulation type used. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Settled modulation type. + * + ******************************************************************************/ + +enum modulation_select_e + spirit_radio_get_modulation(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Read the modulation register MOD0 */ + + (void)spirit_reg_read(spirit, MOD0_BASE, ®val, 1); + + /* Return the modulation type */ + + return (enum modulation_select_e) (regval & 0x70); +} + +/****************************************************************************** + * Name: spirit_radio_enable_cwtxmode + * + * Description: + * Enables or Disables the Continuous Wave transmit mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for power ramping. This parameter can be: S_ENABLE + * or S_DISABLE . + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_enable_cwtxmode(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)); + + /* Read the modulation register MOD0 and mask the CW field */ + + ret = spirit_reg_read(spirit, MOD0_BASE, ®val, 1); + if (ret >= 0) + { + if (newstate == S_ENABLE) + { + regval |= MOD0_CW; + } + else + { + regval &= (~MOD0_CW); + } + + /* Write the new value to the MOD0 register */ + + ret = spirit_reg_write(spirit, MOD0_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_set_ookpeackdecay + * + * Description: + * Sets the OOK Peak Decay. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * ookdelay - Peak decay control for OOK. + * + * Returned Value: + * Zero (OK) is returned on succes; a negated errnor value is returned on any + * failure. + * + ******************************************************************************/ + +int spirit_radio_set_ookpeackdecay(FAR struct spirit_library_s *spirit, + enum spirit_ookpeakdelay_e ookdelay) +{ + uint8_t regval; + + /* Check the parameters */ + + DEBUGASSERT(IS_OOK_PEAK_DECAY(ookdelay)); + + /* Read the RSSI_FLT register */ + + spirit_reg_read(spirit, RSSI_FLT_BASE, ®val, 1); + + /* Mask the other fields and set OOK Peak Decay */ + + regval &= 0xfc; + regval |= ookdelay; + + /* Write the RSSI_FLT register to set the new OOK peak dacay value */ + + return spirit_reg_write(spirit, RSSI_FLT_BASE, ®val, 1); +} + +/****************************************************************************** + * Name: spirit_radio_get_ookpeackdecay + * + * Description: + * Returns the OOK Peak Decay. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Ook peak decay value. + * + ******************************************************************************/ + +enum spirit_ookpeakdelay_e + spirit_radio_get_ookpeackdecay(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Read the OOK peak decay register RSSI_FLT_BASE */ + + (void)spirit_reg_read(spirit, RSSI_FLT_BASE, ®val, 1); + + /* Returns the OOK peak decay */ + + return (enum spirit_ookpeakdelay_e) (regval & 0x03); +} + +/****************************************************************************** + * Name: spirit_radio_convert_power2reg * * Description: * Returns the PA register value that corresponds to the passed dBm power. @@ -1431,16 +2180,16 @@ int spirit_radio_convert_chbandwidth(FAR struct spirit_library_s *spirit, * * Input Parameters: * spirit - Reference to a Spirit library state structure instance - * fbase Frequency base expressed in Hz. - * powerdbm Desired power in dBm. + * fbase - Frequency base expressed in Hz. + * power - Desired power in dBm. * * Returned Value: * Register value as byte. * ******************************************************************************/ -uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, - uint32_t fbase, float powerdbm) +uint8_t spirit_radio_convert_power2reg(FAR struct spirit_library_s *spirit, + uint32_t fbase, float power) { float pavalue; uint8_t i = 0; @@ -1468,20 +2217,20 @@ uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, } j = 1; - if (powerdbm > 0 && + if (power > 0 && 13.0 / g_power_factors[i][2] - g_power_factors[i][3] / - g_power_factors[i][2] < powerdbm) + g_power_factors[i][2] < power) { j = 0; } - else if (powerdbm <= 0 && + else if (power <= 0 && 40.0 / g_power_factors[i][2] - g_power_factors[i][3] / - g_power_factors[i][2] > powerdbm) + g_power_factors[i][2] > power) { j = 2; } - pavalue = g_power_factors[i][2 * j] * powerdbm + + pavalue = g_power_factors[i][2 * j] * power + g_power_factors[i][2 * j + 1]; if (pavalue < 1) @@ -1496,20 +2245,208 @@ uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, return (uint8_t)pavalue; } +/****************************************************************************** + * Name: spirit_radio_convert_reg2power + * + * Description: + * Returns the dBm power that corresponds to the value of PA register. + * + * NOTE: The power interpolation curves used by this function have been + * extracted by measurements done on the divisional evaluation boards. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fbase - Frequency base expressed in Hz. + * regval - Register value of the PA. + * + * Returned Value: + * Power in dBm as float. + * + ******************************************************************************/ + +float spirit_radio_convert_reg2power(FAR struct spirit_library_s *spirit, + uint32_t fbase, uint8_t regval) +{ + uint8_t i = 0; + uint8_t j = 0; + float power; + + if (regval == 0 || regval > 90) + { + return -130.0; + } + + if (IS_FREQUENCY_BAND_HIGH(fbase)) + { + i = 0; + if (fbase < 900000000) + { + i = 1; /* 868 */ + } + } + else if (IS_FREQUENCY_BAND_MIDDLE(fbase)) + { + i = 2; + } + else if (IS_FREQUENCY_BAND_LOW(fbase)) + { + i = 3; + } + else if (IS_FREQUENCY_BAND_VERY_LOW(fbase)) + { + i = 4; + } + + j = 1; + if (regval < 13) + { + j = 0; + } + else if (regval > 40) + { + j = 2; + } + + power = (((float)regval) / g_power_factors[i][2 * j] - + g_power_factors[i][2 * j + 1] / g_power_factors[i][2 * j]); + + return power; +} + +/****************************************************************************** + * Name: spirit_radio_config_patable + * + * Description: + * Configures the Power Amplifier Table and registers with value expressed + * in dBm. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * nlevels - Number of levels to set. This parameter must be in the range + * [0:7]. + * width - Step width expressed in terms of bit period units Tb/8. This + * parameter must be in the range [1:4]. + * load - The of the possible value of the enum type enum + * pirit_paload_capacitor_e. + * + * LOAD_0_PF No additional PA load capacitor + * LOAD_1_2_PF 1.2pF additional PA load capacitor + * LOAD_2_4_PF 2.4pF additional PA load capacitor + * LOAD_3_6_PF 3.6pF additional PA load capacitor + * + * table - Pointer to an array of PA values in dbm between + * [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dbm. The first element must + * be the lower level (PA_LEVEL[0]) value and the last element + * the higher level one (PA_LEVEL[paLevelMaxIndex]). + * + * Returned Value: + * Zero (OK) on success. A negated errno value is returned on any failure. + * + ******************************************************************************/ + +int spirit_radio_config_patable(FAR struct spirit_library_s *spirit, + uint8_t nlevels, uint8_t width, + enum spirit_paload_capacitor_e load, + FAR float *table) +{ + uint8_t palevel[9]; + uint8_t regaddr; + uint8_t value; + uint32_t fbase = spirit_radio_get_basefrequency(spirit); + int i; + + /* Check the parameters */ + + DEBUGASSERT(IS_PA_MAX_INDEX(nlevels)); + DEBUGASSERT(IS_PA_STEP_WIDTH(width)); + DEBUGASSERT(IS_PA_LOAD_CAP(load)); + + /* Check the PA level in dBm is in the range and calculate the PA_LEVEL value + * to write in the corresponding register using the linearization formula */ + + for (i = 0; i <= nlevels; i++) + { + DEBUGASSERT(IS_PAPOWER_DBM(*table)); + value = spirit_radio_convert_power2reg(spirit, fbase, *table); + palevel[nlevels - i] = value; + table++; + } + + /* Set the PA_POWER[0] register */ + + palevel[nlevels + 1] = load | (width - 1) << 3 | nlevels; + + /* Get the base address */ + + regaddr = PA_POWER8_BASE + 7 - nlevels; + + /* Configuresthe PA_POWER registers */ + + return spirit_reg_write(spirit, regaddr, palevel, nlevels + 2); +} + +/****************************************************************************** + * Name: regaddr + * + * Description: + * Returns the Power Amplifier Table and registers, returning values in dBm. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * nlevels - Pointer to the number of levels settled. This parameter must + * be in the range [0:7]. + * table - Pointer to an array of 8 elements containing the PA value in dbm. + * The first element will be the PA_LEVEL_0 and the last element + * will be PA_LEVEL_7. Any value higher than PA_UPPER_LIMIT implies + ( no output power (output stage is in high impedance). + * + * Returned Value: + * Zero (OK) on success. A negated errno value is returned on any failure. + * + ******************************************************************************/ + +int spirit_radio_get_patable(FAR struct spirit_library_s *spirit, + FAR uint8_t *nlevels, FAR float *table) +{ + uint32_t fbase = spirit_radio_get_basefrequency(spirit); + uint8_t palevel[9]; + int ret; + int i; + + /* Reads the PA_LEVEL_x registers and the PA_POWER_0 register */ + + ret = spirit_reg_read(spirit, PA_POWER8_BASE, palevel, 9); + if (ret >= 0) + { + /* Fill the PAtable */ + + for (i = 7; i >= 0; i--) + { + *table++ = spirit_radio_convert_reg2power(spirit, fbase, palevel[i]); + } + + /* Return the settled index */ + + *nlevels = palevel[8] & 0x07; + } + + return ret; +} + /****************************************************************************** * Name: spirit_radio_set_palevel * * Description: * Sets a specific PA_LEVEL register, with a value given in dBm. * - * NOTE: This function makes use of the @ref spirit_radio_dbm2reg fcn to - * interpolate the power value. + * NOTE: This function makes use of the spirit_radio_convert_power2reg fcn + * to interpolate the power value. * * Input Parameters: - * spirit - Reference to a Spirit library state structure instance - * ndx - PA_LEVEL to set. This parameter shall be in the range [0:7]. - * powerdbm - PA value to write expressed in dBm . Be sure that this values - * is in the correct range [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dBm. + * spirit - Reference to a Spirit library state structure instance + * ndx - PA_LEVEL to set. This parameter shall be in the range [0:7]. + * power - PA value to write expressed in dBm . Be sure that this values + * is in the correct range [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dBm. * * Returned Value: * Zero (OK) on success. A negated errno value is returned on any failure. @@ -1517,7 +2454,7 @@ uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, ******************************************************************************/ int spirit_radio_set_palevel(FAR struct spirit_library_s *spirit, - uint8_t ndx, float powerdbm) + uint8_t ndx, float power) { uint32_t basefrequency; uint8_t address; @@ -1526,12 +2463,12 @@ int spirit_radio_set_palevel(FAR struct spirit_library_s *spirit, /* Check the parameters */ DEBUGASSERT(IS_PA_MAX_INDEX(ndx)); - DEBUGASSERT(IS_PAPOWER_DBM(powerdbm)); + DEBUGASSERT(IS_PAPOWER_DBM(power)); /* Interpolate the power level */ basefrequency = spirit_radio_get_basefrequency(spirit); - level = spirit_radio_dbm2reg(spirit, basefrequency, powerdbm); + level = spirit_radio_convert_power2reg(spirit, basefrequency, power); /* Sets the base address */ @@ -1571,7 +2508,7 @@ int spirit_radio_set_outputload(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_PA_LOAD_CAP(load)); - /* Reads the PA_POWER_0 register */ + /* Read the PA_POWER_0 register */ ret = spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1); if (ret >= 0) @@ -1613,7 +2550,7 @@ enum spirit_paload_capacitor_e { uint8_t regval; - /* Reads the PA_POWER_0 register */ + /* Read the PA_POWER_0 register */ (void)spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1); @@ -1648,7 +2585,7 @@ int spirit_radio_set_palevel_maxindex(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_PA_MAX_INDEX(ndx)); - /* Reads the PA_POWER_0 register */ + /* Read the PA_POWER_0 register */ ret = spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1); if (ret >= 0) @@ -1692,7 +2629,7 @@ int spirit_radio_afcfreezeonsync(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); - /* Reads the AFC_2 register and configure the AFC Freeze on Sync field */ + /* Read the AFC_2 register and configure the AFC Freeze on Sync field */ ret = spirit_reg_read(spirit, AFC2_BASE, ®val, 1); if (ret >= 0) @@ -1740,7 +2677,7 @@ int spirit_radio_enable_csblanking(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); - /* Reads the ANT_SELECT_CONF_BASE and mask the CS_BLANKING BIT field */ + /* Read the ANT_SELECT_CONF_BASE and mask the CS_BLANKING BIT field */ ret = spirit_reg_read(spirit, ANT_SELECT_CONF_BASE, ®val, 1); if (ret >= 0) @@ -1787,7 +2724,7 @@ int spirit_radio_persistentrx(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); - /* Reads the PROTOCOL0_BASE and mask the PROTOCOL0_PERS_RX_MASK bitfield */ + /* Read the PROTOCOL0_BASE and mask the PROTOCOL0_PERS_RX_MASK bitfield */ ret = spirit_reg_read(spirit, PROTOCOL0_BASE, ®val, 1); if (ret >= 0) @@ -1801,7 +2738,7 @@ int spirit_radio_persistentrx(FAR struct spirit_library_s *spirit, regval &= (~PROTOCOL0_PERS_RX_MASK); } - /* Writes the new value in the PROTOCOL0_BASE register */ + /* Write the new value to the PROTOCOL0_BASE register */ ret = spirit_reg_write(spirit, PROTOCOL0_BASE, ®val, 1); } @@ -1834,7 +2771,7 @@ int spirit_radio_set_refdiv(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); - /* Reads the SYNTH_CONFIG1_BASE and mask the REFDIV bit field */ + /* Read the SYNTH_CONFIG1_BASE and mask the REFDIV bit field */ ret = spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1); if (ret >= 0) @@ -1848,7 +2785,7 @@ int spirit_radio_set_refdiv(FAR struct spirit_library_s *spirit, regval &= 0x7f; } - /* Writes the new value in the SYNTH_CONFIG1_BASE register */ + /* Write the new value to the SYNTH_CONFIG1_BASE register */ ret = spirit_reg_write(spirit, SYNTH_CONFIG1_BASE, ®val, 1); } @@ -1912,7 +2849,7 @@ int spirit_radio_enable_digdivider(FAR struct spirit_library_s *spirit, DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); - /* Reads the XO_RCO_TEST_BASE and mask the PD_CLKDIV bit field */ + /* Read the XO_RCO_TEST_BASE and mask the PD_CLKDIV bit field */ ret = spirit_reg_read(spirit, XO_RCO_TEST_BASE, ®val, 1); if (ret >= 0)