5889ce65f5
commit da782d6cdff5980d71aaa2da5f9c28ab3438d085 Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 29 07:26:48 2017 -0600 Spirit: Completes port of the spirit radio library to NuttX. commit 63f3595c47dca13952d28b518c7f0a8d6ae9037a Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 17:42:51 2017 -0600 Spirit: Bring in a couple ore more radio interface functions. commit 692a27da396b7683749790923d8fa085091764f1 Merge: 27c0a6ec0838f79543dc
Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 15:49:37 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 27c0a6ec0813187f125922c81189a70cf04d83d4 Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 15:47:27 2017 -0600 Spirit: Bring in a couple ore more radio interface functions. commit 96657af2831487724723a60084831619257fd953 Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 14:20:14 2017 -0600 Spirit: Bring in more radio interface functions. commit 640d55399b54a019be68825668fca1446abd082f Merge: 3fcf84a9a247791442a0
Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 12:01:43 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 3fcf84a9a2673e1e1466ce5b114d7b73c257e515 Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 12:00:31 2017 -0600 Spirit: Brings in the last of the PktCommon interfaces. commit d26ebd901ba4ba84910e99b4e728b98c30fa4c0b Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 09:54:52 2017 -0600 Spirit: Add a few more PktCommon interfaces. commit b5cb8041d50233a4abb8fb4d1dcef5428ae2c2b2 Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 09:33:31 2017 -0600 libc/termios: Remember block comments before empty file sections. commit 0fcab2c1c8c74442d40bd5e8c6af50a34f8a5821 Author: Sebastien Lorquet <sebastien@lorquet.fr> Date: Fri Jul 28 09:31:00 2017 -0600 tcdrain implementation based on a new term ioctl commit 797d4adf7d41068c671f0217d369b797b269de1a Author: Stefan Kolb <Stefan.Kolb@avat.de> Date: Fri Jul 28 09:19:04 2017 -0600 We discovered a problem with the samv7 mcan driver which results, under some circumstances, in a very high CPU load. The problem occurs, and is easily reproducible, if the device is connected to a CAN network with a wrongly configured CAN speed (baud rate). In our tests we set the CAN speed of the device to 1000000 and the speed of the other CAN nodes to 500000. The device is restarted and sends a CANopen “bootup message” to the CAN network. This results in huge amount of errors messages on the CAN bus, probably because of the CAN feature for acknowledging error messages. The error messages can’t be read by the device because of the misconfigured CAN speed, instead the CAN chip reports lots of errors, which are reported to the application which uses the CAN driver (CONFIG_CAN_ERRORS is enabled). The CAN errors are reported from the CAN chip via interrupts and thus the interrupt load is very high in this scenario. To fix the problem the driver now disables each RX error interrupt after it is occurred. The RX error interrupts are turned back on if at least one CAN message is received successfully. commit e298f48e96d9e34017dcab8e4d87032862ae9322 Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 28 09:06:26 2017 -0600 Spirit: Bring in PktStack interfaces. commit 4a0f00a7058312dcf6ac392689b9f69112f613ec Merge: 855cf97130b458934ac4
Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 27 18:05:02 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 855cf9713052a851a1daeb3842db2edd6ff6f658 Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 27 18:03:56 2017 -0600 Spirit Network Driver: Add some hooks that will eventually support address filtering. commit 3b3fb24ea86cf8233b034871d5c550f47ab852e6 Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 27 17:13:21 2017 -0600 Spirit: Add a PktStack header file. commit 705e8fff6a21264ab751fb34c107cb109430ac89 Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 27 15:00:03 2017 -0600 Spirit: Bring in last of timer interfaces. commit f8984b2f82e165f5bba132d6b099222d1beb1fbd Merge: cb79778a30f287cc25d6
Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 27 11:57:01 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit cb79778a3044ae97a1cc615dfa24099144f04bd0 Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 27 11:46:31 2017 -0600 Spirit: Bring in last of QI interfaces. commit 0245b330a33aa73531b82ae261b1312be9922e0f Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 27 10:14:34 2017 -0600 Spirit: Add general interfaces. commit 121845a8f229ec2c88e5721da5512135f6624ee5 Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 27 09:41:23 2017 -0600 Spirit: Bring in last of GPIO interfaces. commit 279bfcc92bcd0cfa48c0ed7862fa2b75fbee99b8 Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 26 17:09:19 2017 -0600 Spirit: Add some missing configuration options: Add register -level debug options. commit 4be89324a5908e35afc70373c279f4d05f62b48f Merge: 66e87f9bb3598386ef90
Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 26 15:36:20 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 66e87f9bb3ef75fddf25400bc08475c5e6ad4c30 Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 26 15:19:56 2017 -0600 Spirit: Brings in last of PktBasic logic. commit 8b4c89d6a103003fa04363e2c2ae7b9ee390bf49 Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 26 11:55:50 2017 -0600 Spirit: Bring in AES and MBUS logic. commit d00022d39ab0ce839de29386949481e5c24feff3 Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 26 09:22:03 2017 -0600 Spirit: Bring in remainder of calibration interfaces. commit 40b4b2f902e04293f8940551a97a9a24a48988dd Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 26 08:44:32 2017 -0600 Spirit: Bring in DirectRF interfaces. commit 7c109608e1a2989f3edbc2fd939a2d225fff382a Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 26 07:46:19 2017 -0600 Spirit: Add CSMA support. commit 0f88896595d162c4ac6138e7b1af2fc35c865b3d Author: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 25 18:57:43 2017 -0600 Spirit: Add some initial TX logic to network driver. commit 4dc7058dfcdcf40980578680b7e1a4206dea4ea2 Author: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 25 17:02:11 2017 -0600 Spirit: Completes ports of spirit_management.* files commit c904eef51d929e041b87d0c8aff6fa3c2f895341 Merge: 91e985a877c9ff8cbab9
Author: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 25 15:15:04 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 91e985a87729017a66d19276c4d47681064f95ea Author: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 25 15:13:54 2017 -0600 Spirit: Add a few more functions that will soon be needed for packet transmission. commit b5981d29983907c2194fbc26af4b72ad532bee78 Author: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 25 13:30:07 2017 -0600 Spirit: Finish off some initialization issues; Started some interrupt handling logic. commit c21073e0bc2870b3d9ba40bdfdfd5151ce4f5890 Author: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 25 09:35:52 2017 -0600 Spirit: Completes very basic radio initialization for network driver commit 1b544334361c54f46bcf0ba313c125932e8dafc6 Author: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 25 07:58:30 2017 -0600 Spirit: Add more radio initialization logic... getting closer. commit 45d1047db60843c57d394ec910c63e7c127671e0 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 19:15:33 2017 -0600 Spirit: add some CSMA initialization logic commit bcf55c71336d48947fe19bb09a799169852301c2 Merge: 89e9d426e92fc0fbcf7e
Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 16:47:11 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 89e9d426e91c056e659fccf5e5c4392618f8f777 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 16:44:19 2017 -0600 Update some comments commit 9c5d8a5833350006ed389e898b11c8c8a20e5f4f Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 16:15:54 2017 -0600 Spirit: Rename drivers/wireless/spirit/src to lib. Move Spirit network driver out of IEEE802.15.4 into drivers/wireless/spirit/drivers commit cabc0ec9e6eb558dcb715ab17264383aa0105e7a Merge: 87b616414a6bd744c4b3
Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 15:38:40 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 87b616414a79c01a71acea78f8258e05325c1996 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 15:37:27 2017 -0600 Spirit radio driver is mutating into a standalone network driver. commit 507798233868a661ae8adad3e3aa117075a7a146 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 13:32:08 2017 -0600 Spirit: More radio initialization logic commit 33af25704ce9ca83d576300d153cfe31cc6d2576 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 12:19:14 2017 -0600 Spirit: Beginning of radio initialization logic commit 97b20014c016e55952a8f9d8f4ae29e2cc555b23 Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 24 09:42:06 2017 -0600 Spirit: More initialization logic. commit 295d8e27824c0417fccea2344b30bb5c93ffbabe Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 23 15:39:53 2017 -0600 Spirit: Add header file containing enumeration of commands. commit 8a2d9dd8eb9cc70cbcdd1b913fc9022b9c9ec8da Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 23 11:33:50 2017 -0600 Spirit: Add GPIO initialization logic commit 8b6d80c44f92024c45a6ba63ba1af3fdafe94dc3 Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 23 10:07:25 2017 -0600 Spirit: Add interrupt control logic. commit 423f846fe5c914f92a4bfea4d9d1fa33de1c77a5 Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 19:06:52 2017 -0600 Spirit: Yet a little more radio initialization logic. commit 5895b979823e51ddde5ad52e6de66a8ad662e883 Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 15:36:05 2017 -0600 Spirit: A little more radio initialization logic. commit 86311ab30aad386203c181c792847dd1d37f9a02 Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 13:02:32 2017 -0600 Spirit: A miniscule amount of radio initialization logic. commit ad55e89d5ee12ea1eeea95fcd38ff3da0db4416a Merge: 90a7666655f4e46b0da7
Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 10:56:30 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 90a766665534b05da0157dbc383cb06a98c86a79 Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 10:52:52 2017 -0600 Spirit1: A few fixes for a clean build of initial configuration (not much there yet) commit bbbf04c223230a52a7705a2161128265cfbaa480 Merge: 623d54a7f72319ea53a9
Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 09:53:57 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 623d54a7f719e9032099f88f38203efee4b80722 Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 09:43:52 2017 -0600 b-l475e-iot01a: Add a configuration for testing sprit radio. commit d309d73d9f4665f9d870eb03531f450043d9389d Merge: 52c3ddfae6d88dc9b2e5
Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 09:02:06 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 52c3ddfae6802e111c2b5cf1207baf21a61dd00b Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 22 08:33:04 2017 -0600 Spirit: Add register definition header file. commit 8d842ab5e8f9ca653b42f9ee88dc279f06b4fa98 Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 21 17:27:03 2017 -0600 b-l475e-iot01a: Add initial, unverified support for the SPSRGF/Spirit1 module. commit 73d902a1048616fb9c2dd2147cabcd8ee78e19ac Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 21 15:49:43 2017 -0600 Spirit: Fixes to get skeleton IEEE 802.15.4 driver build. commit ebc5a8387bb94f0cc3827533795f3e4a33207e67 Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 21 15:16:29 2017 -0600 Spirit1: Add framework for IEEE 802.15.4 driver. Does not yet build. commit 52e195a7ae14ddb18bdd56258f4877381d2501ca Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 21 14:02:42 2017 -0600 Spirit: A little more SPI logic. commit 90048d0c5b8a5af4d81a15d99535c84ed38d8ae9 Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 21 11:19:06 2017 -0600 Spirit: Build directories setup. Some initial files added, mostly just to verify build. commit 8273a381ac1f6bb081b292b5e73226185e9e634c Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 21 08:34:04 2017 -0600 USB composite: Remove references to CDC/ACM and USB MSC from composite logic. They are no longer coupled.
4755 lines
129 KiB
C
4755 lines
129 KiB
C
/******************************************************************************
|
|
* drivers/wireless/spirit/lib/spirit_radio.c
|
|
* This file provides all the low level API to manage Analog and Digital radio
|
|
* part of SPIRIT.
|
|
*
|
|
* Copyright(c) 2015 STMicroelectronics
|
|
* Author: VMA division - AMS
|
|
* Version 3.2.2 08-July-2015
|
|
*
|
|
* Adapted for NuttX by:
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
*
|
|
* 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 <sys/types.h>
|
|
#include <stdint.h>
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
|
|
#include "spirit_config.h"
|
|
#include "spirit_types.h"
|
|
#include "spirit_management.h"
|
|
#include "spirit_calibration.h"
|
|
#include "spirit_radio.h"
|
|
#include "spirit_spi.h"
|
|
|
|
/******************************************************************************
|
|
* Pre-processor Definitions
|
|
******************************************************************************/
|
|
|
|
#define XTAL_FLAG(xtalFrequency) \
|
|
(xtalFrequency >= 25e6) ? XTAL_FLAG_26_MHz : XTAL_FLAG_24_MHz
|
|
#define ROUND(a) \
|
|
(((a - (uint32_t)a) > 0.5) ? (uint32_t)a + 1 : (uint32_t)a)
|
|
|
|
/* Returns the absolute value. */
|
|
|
|
#define S_ABS(a) ((a) > 0 ? (a) : -(a))
|
|
|
|
/******************************************************************************
|
|
* Private Data
|
|
******************************************************************************/
|
|
|
|
/* Factor is: B/2 used in the formula for SYNTH word calculation */
|
|
|
|
static const uint8_t g_vectc_bhalf[4] =
|
|
{
|
|
(HIGH_BAND_FACTOR / 2),
|
|
(MIDDLE_BAND_FACTOR / 2),
|
|
(LOW_BAND_FACTOR / 2),
|
|
(VERY_LOW_BAND_FACTOR / 2)
|
|
};
|
|
|
|
/* BS value to write in the SYNT0 register according to the selected band */
|
|
|
|
static const uint8_t g_vectc_bandval[4] =
|
|
{
|
|
SYNT0_BS_6, SYNT0_BS_12, SYNT0_BS_16, SYNT0_BS_32
|
|
};
|
|
|
|
/* It represents the available channel bandwidth times 10 for 26 Mhz xtal.
|
|
* NOTE: The channel bandwidth for others xtal frequencies can be computed
|
|
* since this table multiplying the current table by a factor
|
|
* xtal_frequency/26e6.
|
|
*/
|
|
|
|
static const uint16_t g_vectn_bandwidth[90] =
|
|
{
|
|
8001, 7951, 7684, 7368, 7051, 6709, 6423, 5867, 5414,
|
|
4509, 4259, 4032, 3808, 3621, 3417, 3254, 2945, 2703,
|
|
2247, 2124, 2015, 1900, 1807, 1706, 1624, 1471, 1350,
|
|
1123, 1062, 1005, 950, 903, 853, 812, 735, 675,
|
|
561, 530, 502, 474, 451, 426, 406, 367, 337,
|
|
280, 265, 251, 237, 226, 213, 203, 184, 169,
|
|
140, 133, 126, 119, 113, 106, 101, 92, 84,
|
|
70, 66, 63, 59, 56, 53, 51, 46, 42,
|
|
35, 33, 31, 30, 28, 27, 25, 23, 21,
|
|
18, 17, 16, 15, 14, 13, 13, 12, 11
|
|
};
|
|
|
|
/* These values are used to interpolate the power curves. Interpolation
|
|
* curves are linear in the following 3 regions:
|
|
*
|
|
* - reg value: 1 to 13 (up region)
|
|
* - reg value: 13 to 40 (mid region)
|
|
* - reg value: 41 to 90 (low region)
|
|
*
|
|
* power_reg = m*power_dBm + q
|
|
*
|
|
* For each band the order is: {m-up, q-up, m-mid, q-mid, m-low, q-low}.
|
|
*
|
|
* NOTE: The power interpolation curves have been extracted by
|
|
* measurements done on the divisional evaluation boards.
|
|
*/
|
|
|
|
static const float g_power_factors[5][6] =
|
|
{
|
|
{-2.11, 25.66, -2.11, 25.66, -2.00, 31.28}, /* 915 */
|
|
{-2.04, 23.45, -2.04, 23.45, -1.95, 27.66}, /* 868 */
|
|
{-3.48, 38.45, -1.89, 27.66, -1.92, 30.23}, /* 433 */
|
|
{-3.27, 35.43, -1.80, 26.31, -1.89, 29.61}, /* 315 */
|
|
{-4.18, 50.66, -1.80, 30.04, -1.86, 32.22}, /* 169 */
|
|
};
|
|
|
|
/* It represents the available VCO frequencies */
|
|
|
|
static const uint16_t g_vectn_vcofreq[16] =
|
|
{
|
|
4644, 4708, 4772, 4836, 4902, 4966, 5030, 5095,
|
|
5161, 5232, 5303, 5375, 5448, 5519, 5592, 5663
|
|
};
|
|
|
|
/******************************************************************************
|
|
* Public Functions
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_initialize
|
|
*
|
|
* Description:
|
|
* Initializes the SPIRIT analog and digital radio part according to the
|
|
* specified parameters in the radioinit.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* radioinit - Pointer to a struct radio_init_s that contains the
|
|
*
|
|
* Returned Value:
|
|
* Error code: 0=no error, <0=error during calibration of VCO.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_initialize(FAR struct spirit_library_s *spirit,
|
|
FAR const struct radio_init_s *radioinit)
|
|
{
|
|
float ifoff;
|
|
int32_t offset;
|
|
int16_t fcoffset;
|
|
uint8_t anaoffset;
|
|
uint8_t digregs[4];
|
|
uint8_t anaregs[8];
|
|
uint8_t drm;
|
|
uint8_t dre;
|
|
uint8_t fdevm;
|
|
uint8_t fdeve;
|
|
uint8_t bwm;
|
|
uint8_t bwe;
|
|
uint8_t regval;
|
|
uint8_t value;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_FREQUENCY_BAND(radioinit->base_frequency));
|
|
DEBUGASSERT(IS_MODULATION_SELECTED(radioinit->modselect));
|
|
DEBUGASSERT(IS_DATARATE(radioinit->datarate));
|
|
DEBUGASSERT(IS_FREQUENCY_OFFSET(offset, spirit->xtal_frequency));
|
|
DEBUGASSERT(IS_CHANNEL_SPACE
|
|
(radioinit->chspace, spirit->xtal_frequency));
|
|
DEBUGASSERT(IS_F_DEV(radioinit->freqdev, spirit->xtal_frequency));
|
|
|
|
/* Workaround for Vtune */
|
|
|
|
value = 0xa0;
|
|
ret = spirit_reg_write(spirit, 0x9f, &value, 1);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Calculates the offset respect to RF frequency and according to xtal_ppm
|
|
* parameter: (xtal_ppm*FBase)/10^6
|
|
*/
|
|
|
|
offset = (int32_t)(((float)radioinit->xtal_offset_ppm *
|
|
radioinit->base_frequency) / PPM_FACTOR);
|
|
|
|
/* Disable the digital, ADC, SMPS reference clock divider if fXO > 24MHz or
|
|
* fXO < 26MHz
|
|
*/
|
|
|
|
ret = spirit_command(spirit, COMMAND_STANDBY);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
do
|
|
{
|
|
volatile uint8_t i;
|
|
|
|
/* Delay for state transition */
|
|
|
|
for (i = 0; i != 0xff; i++);
|
|
|
|
/* Read the MC_STATUS register */
|
|
|
|
ret = spirit_update_status(spirit);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
while (spirit->u.state.MC_STATE != MC_STATE_STANDBY);
|
|
|
|
if (spirit->xtal_frequency < DOUBLE_XTAL_THR)
|
|
{
|
|
ret = spirit_radio_enable_digdivider(spirit, S_DISABLE);
|
|
DEBUGASSERT(IS_CH_BW(radioinit->bandwidth, spirit->xtal_frequency));
|
|
}
|
|
else
|
|
{
|
|
ret = spirit_radio_enable_digdivider(spirit, S_ENABLE);
|
|
DEBUGASSERT(IS_CH_BW(radioinit->bandwidth, (spirit->xtal_frequency >> 1)));
|
|
}
|
|
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Go to READY state */
|
|
|
|
ret = spirit_command(spirit, COMMAND_READY);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
do
|
|
{
|
|
volatile uint8_t i;
|
|
|
|
/* Delay for state transition */
|
|
|
|
for (i = 0; i != 0xff; i++);
|
|
|
|
/* Read the MC_STATUS register */
|
|
|
|
ret = spirit_update_status(spirit);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
while (spirit->u.state.MC_STATE != MC_STATE_READY);
|
|
|
|
/* Calculates the FC_OFFSET parameter and cast as signed int: offset =
|
|
* (Fxtal/2^18)*FC_OFFSET
|
|
*/
|
|
|
|
fcoffset = (int16_t)(((float)offset * FBASE_DIVIDER) /
|
|
spirit->xtal_frequency);
|
|
anaregs[2] = (uint8_t)((((uint16_t)fcoffset) >> 8) & 0x0f);
|
|
anaregs[3] = (uint8_t)fcoffset;
|
|
|
|
/* Calculates the channel space factor */
|
|
|
|
anaregs[0] = ((uint32_t)radioinit->chspace << 9) /
|
|
(spirit->xtal_frequency >> 6) + 1;
|
|
|
|
spirit_management_initcommstate(spirit, radioinit->base_frequency);
|
|
|
|
/* 2nd order DEM algorithm enabling */
|
|
|
|
ret = spirit_reg_read(spirit, 0xa3, ®val, 1);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
regval &= ~0x02;
|
|
ret = spirit_reg_write(spirit, 0xa3, ®val, 1);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Check the channel center frequency is in one of the possible range */
|
|
|
|
DEBUGASSERT(IS_FREQUENCY_BAND((radioinit->base_frequency +
|
|
((fcoffset * spirit->xtal_frequency) / FBASE_DIVIDER) +
|
|
radioinit->chspace * radioinit->chnum)));
|
|
|
|
/* Calculates the datarate mantissa and exponent */
|
|
|
|
ret = spirit_radio_convert_datarate(spirit, radioinit->datarate,
|
|
&drm, &dre);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
digregs[0] = (uint8_t)(drm);
|
|
digregs[1] = (uint8_t)(radioinit->modselect | dre);
|
|
|
|
/* Read the fdev register to preserve the clock recovery algo bit */
|
|
|
|
ret = spirit_reg_read(spirit, 0x1c, ®val, 1);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Calculates the frequency deviation mantissa and exponent */
|
|
|
|
ret = spirit_radio_convert_freqdev(spirit, radioinit->freqdev,
|
|
&fdevm, &fdeve);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
digregs[2] = (uint8_t)((fdeve << 4) | (regval & 0x08) | fdevm);
|
|
|
|
/* Calculates the channel filter mantissa and exponent */
|
|
|
|
ret = spirit_radio_convert_chbandwidth(spirit, radioinit->bandwidth, &bwm, &bwe);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
digregs[3] = (uint8_t)((bwm << 4) | bwe);
|
|
|
|
ifoff = (3.0 * 480140) / (spirit->xtal_frequency >> 12) - 64;
|
|
anaoffset = ROUND(ifoff);
|
|
|
|
if (spirit->xtal_frequency < DOUBLE_XTAL_THR)
|
|
{
|
|
/* if offset digital is the same in case of single xtal */
|
|
|
|
anaregs[1] = anaoffset;
|
|
}
|
|
else
|
|
{
|
|
ifoff = (3.0 * 480140) / (spirit->xtal_frequency >> 13) - 64;
|
|
|
|
/* ... otherwise recompute it */
|
|
|
|
anaregs[1] = ROUND(ifoff);
|
|
}
|
|
|
|
#if 0
|
|
if (spirit->xtal_frequency == 24000000)
|
|
{
|
|
anaoffset = 0xb6;
|
|
anaregs[1] = 0xb6;
|
|
}
|
|
|
|
if (spirit->xtal_frequency == 25000000)
|
|
{
|
|
anaoffset = 0xac;
|
|
anaregs[1] = 0xac;
|
|
}
|
|
|
|
if (spirit->xtal_frequency == 26000000)
|
|
{
|
|
anaoffset = 0xa3;
|
|
anaregs[1] = 0xa3;
|
|
}
|
|
|
|
if (spirit->xtal_frequency == 48000000)
|
|
{
|
|
anaoffset = 0x3b;
|
|
anaregs[1] = 0xb6;
|
|
}
|
|
|
|
if (spirit->xtal_frequency == 50000000)
|
|
{
|
|
anaoffset = 0x36;
|
|
anaregs[1] = 0xac;
|
|
}
|
|
|
|
if (spirit->xtal_frequency == 52000000)
|
|
{
|
|
anaoffset = 0x31;
|
|
anaregs[1] = 0xa3;
|
|
}
|
|
#endif
|
|
|
|
ret = spirit_reg_write(spirit, IF_OFFSET_ANA_BASE, &anaoffset, 1);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Set Xtal configuration */
|
|
|
|
if (spirit->xtal_frequency > DOUBLE_XTAL_THR)
|
|
{
|
|
enum xtal_flag_e xtlflag = XTAL_FLAG((spirit->xtal_frequency / 2));
|
|
ret = spirit_radio_set_xtalflag(spirit, xtlflag);
|
|
}
|
|
else
|
|
{
|
|
enum xtal_flag_e xtlflag = XTAL_FLAG(spirit->xtal_frequency);
|
|
ret = spirit_radio_set_xtalflag(spirit, xtlflag);
|
|
}
|
|
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Sets the channel number in the corresponding register */
|
|
|
|
ret = spirit_reg_write(spirit, CHNUM_BASE, &radioinit->chnum, 1);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Configures the Analog Radio registers */
|
|
|
|
ret = spirit_reg_write(spirit, CHSPACE_BASE, anaregs, 4);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Configures the Digital Radio registers */
|
|
|
|
ret = spirit_reg_write(spirit, MOD1_BASE, digregs, 4);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Enable the freeze option of the AFC on the SYNC word */
|
|
|
|
ret = spirit_radio_afcfreezeonsync(spirit, S_ENABLE);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Set the IQC correction optimal value */
|
|
|
|
anaregs[0] = 0x80;
|
|
anaregs[1] = 0xe3;
|
|
|
|
ret = spirit_reg_write(spirit, 0x99, anaregs, 2);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
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
|
|
*
|
|
* Description:
|
|
* Sets the Xtal configuration in the ANA_FUNC_CONF0 register.
|
|
*
|
|
* 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
|
|
*
|
|
* Returned Value:
|
|
* Error code: 0=no error, <0=error during calibration of VCO.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_xtalflag(FAR struct spirit_library_s *spirit,
|
|
enum xtal_flag_e xtalflag)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_XTAL_FLAG(xtalflag));
|
|
|
|
/* Read the ANA_FUNC_CONF_0 register */
|
|
|
|
ret = spirit_reg_read(spirit, ANA_FUNC_CONF0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (xtalflag == XTAL_FLAG_26_MHz)
|
|
{
|
|
regval |= SELECT_24_26_MHZ_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~SELECT_24_26_MHZ_MASK);
|
|
}
|
|
|
|
/* Sets the 24_26MHz_SELECT field in the ANA_FUNC_CONF_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, ANA_FUNC_CONF0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_xtalflag
|
|
*
|
|
* Description:
|
|
* Returns the Xtal configuration in the ANA_FUNC_CONF0 register.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* XtalFrequency Settled Xtal configuration.
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum xtal_flag_e spirit_radio_get_xtalflag(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the Xtal configuration in the ANA_FUNC_CONF_0 register and return
|
|
* the value.
|
|
*/
|
|
|
|
(void)spirit_reg_read(spirit, ANA_FUNC_CONF0_BASE, ®val, 1);
|
|
|
|
return (enum xtal_flag_e)((regval & 0x40) >> 6);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_search_wcp
|
|
*
|
|
* Description:
|
|
* Returns the charge pump word for a given VCO frequency.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* fc - Channel center frequency expressed in Hz. This parameter may
|
|
* be a value in one of the following ranges:
|
|
*
|
|
* High_Band: from 779 MHz to 915 MHz
|
|
* Middle Band: from 387 MHz to 470 MHz
|
|
* Low Band: from 300 MHz to 348 MHz
|
|
* Very low Band: from 150 MHz to 174 MHz
|
|
*
|
|
* Returned Value:
|
|
* Charge pump word.
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_search_wcp(FAR struct spirit_library_s *spirit,
|
|
uint32_t fc)
|
|
{
|
|
uint32_t vcofreq;
|
|
uint8_t bfactor;
|
|
int8_t i;
|
|
|
|
/* Check the channel center frequency is in one of the possible range */
|
|
|
|
DEBUGASSERT(IS_FREQUENCY_BAND(fc));
|
|
|
|
/* Search the operating band */
|
|
|
|
if (IS_FREQUENCY_BAND_HIGH(fc))
|
|
{
|
|
bfactor = HIGH_BAND_FACTOR;
|
|
}
|
|
else if (IS_FREQUENCY_BAND_MIDDLE(fc))
|
|
{
|
|
bfactor = MIDDLE_BAND_FACTOR;
|
|
}
|
|
else if (IS_FREQUENCY_BAND_LOW(fc))
|
|
{
|
|
bfactor = LOW_BAND_FACTOR;
|
|
}
|
|
else
|
|
{
|
|
bfactor = VERY_LOW_BAND_FACTOR;
|
|
}
|
|
|
|
/* Calculates the VCO frequency VCOFreq = fc*B */
|
|
|
|
vcofreq = (fc / 1000000) * bfactor;
|
|
|
|
/* Search in the vco frequency array the charge pump word */
|
|
|
|
if (vcofreq >= g_vectn_vcofreq[15])
|
|
{
|
|
i = 15;
|
|
}
|
|
else
|
|
{
|
|
/* Search the value */
|
|
|
|
for (i = 0; i < 15 && vcofreq > g_vectn_vcofreq[i]; i++);
|
|
|
|
/* Be sure that it is the best approssimation */
|
|
|
|
if (i != 0 &&
|
|
g_vectn_vcofreq[i] - vcofreq > vcofreq - g_vectn_vcofreq[i - 1])
|
|
{
|
|
i--;
|
|
}
|
|
}
|
|
|
|
/* Return index */
|
|
|
|
return (i & 7);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_synthword
|
|
*
|
|
* Description:
|
|
* Returns the synth word.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* 32-bit Synth word. Errors are not reported.
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint32_t spirit_radio_get_synthword(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regvalues[4];
|
|
|
|
/* 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) +
|
|
(((uint32_t)(regvalues[1])) << 13) +
|
|
(((uint32_t)(regvalues[2])) << 5) +
|
|
(((uint32_t)(regvalues[3])) >> 3));
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_synthword
|
|
*
|
|
* Description:
|
|
* Sets the SYNTH registers.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* synthword - The synth word to write in the SYNTH[3:0] registers.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_synthword(FAR struct spirit_library_s *spirit,
|
|
uint32_t synthword)
|
|
{
|
|
uint8_t regvalues[4];
|
|
uint8_t synt0;
|
|
int ret;
|
|
|
|
/* Read the SYNT0 register */
|
|
|
|
ret = spirit_reg_read(spirit, SYNT0_BASE, &synt0, 1);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Mask the Band selected field */
|
|
|
|
synt0 &= 0x07;
|
|
|
|
/* Build the array for SYNTH registers */
|
|
|
|
regvalues[0] = (uint8_t)((synthword >> 21) & (0x0000001f));
|
|
regvalues[1] = (uint8_t)((synthword >> 13) & (0x000000ff));
|
|
regvalues[2] = (uint8_t)((synthword >> 5) & (0x000000ff));
|
|
regvalues[3] = (uint8_t)(((synthword & 0x0000001f) << 3) | synt0);
|
|
|
|
/* Write the synth word to the SYNTH registers */
|
|
|
|
ret = spirit_reg_write(spirit, SYNT3_BASE, regvalues, 4);
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_band
|
|
*
|
|
* Description:
|
|
* Sets the operating band.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* band - The band to set. This parameter can be one of following values:
|
|
* HIGH_BAND High_Band selected: from 779 MHz to 915 MHz
|
|
* MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz
|
|
* LOW_BAND: Low Band selected: from 300 MHz to 348 MHz
|
|
* VERY_LOW_BAND: Very low Band selected: from 150 MHz to 174 MHz
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_band(FAR struct spirit_library_s *spirit,
|
|
enum spirit_bandselect_e band)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_BAND_SELECTED(band));
|
|
|
|
/* Read the SYNT0 register */
|
|
|
|
ret = spirit_reg_read(spirit, SYNT0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Mask the SYNTH[4;0] field and write the BS value */
|
|
|
|
regval &= 0xf8;
|
|
regval |= g_vectc_bandval[band];
|
|
|
|
/* Configures the SYNT0 register setting the operating band */
|
|
|
|
ret = spirit_reg_write(spirit, SYNT0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_band
|
|
*
|
|
* Description:
|
|
* Returns the operating band.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* BandSelect Settled band. This returned value may be one of the
|
|
* following values:
|
|
* HIGH_BAND High_Band selected: from 779 MHz to 915 MHz
|
|
* MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz
|
|
* LOW_BAND: Low Band selected: from 300 MHz to 348 MHz
|
|
* VERY_LOW_BAND: Very low Band selected: from 150 MHz to 174 MHz
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_bandselect_e
|
|
spirit_radio_get_band(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the SYNT0 register */
|
|
|
|
(void)spirit_reg_read(spirit, SYNT0_BASE, ®val, 1);
|
|
|
|
/* Mask the Band selected field */
|
|
|
|
if ((regval & 0x07) == SYNT0_BS_6)
|
|
{
|
|
return HIGH_BAND;
|
|
}
|
|
else if ((regval & 0x07) == SYNT0_BS_12)
|
|
{
|
|
return MIDDLE_BAND;
|
|
}
|
|
else if ((regval & 0x07) == SYNT0_BS_16)
|
|
{
|
|
return LOW_BAND;
|
|
}
|
|
else
|
|
{
|
|
return VERY_LOW_BAND;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* 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
|
|
*
|
|
* Description:
|
|
* Sets the channel space factor in channel space register. The channel
|
|
* spacing step is computed as F_Xo/32768.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* chspace - The channel space expressed in Hz.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
|
* any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_chspace(FAR struct spirit_library_s *spirit,
|
|
uint32_t chspace)
|
|
{
|
|
uint8_t factor;
|
|
|
|
/* Round to the nearest integer */
|
|
|
|
factor = ((uint32_t)chspace * CHSPACE_DIVIDER) / spirit->xtal_frequency;
|
|
|
|
/* Write value into the register */
|
|
|
|
return spirit_reg_write(spirit, CHSPACE_BASE, &factor, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_chspace
|
|
*
|
|
* Description:
|
|
* Returns the channel space register.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Channel space. The channel space is:
|
|
*
|
|
* CS = channel_space_factor x XtalFrequency/2^15
|
|
*
|
|
* where channel_space_factor is the CHSPACE register value.
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint32_t spirit_radio_get_chspace(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t factor;
|
|
|
|
/* Read the CHSPACE register, calculate the channel space and return it */
|
|
|
|
(void)spirit_reg_read(spirit, CHSPACE_BASE, &factor, 1);
|
|
|
|
/* Compute the Hertz value and return it */
|
|
|
|
return ((factor * spirit->xtal_frequency) / CHSPACE_DIVIDER);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* 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)
|
|
{
|
|
enum spirit_bandselect_e band;
|
|
uint32_t synthword;
|
|
uint32_t fbase;
|
|
int32_t offset;
|
|
int16_t fcoffset;
|
|
uint8_t refdiv;
|
|
uint8_t tmp[2];
|
|
|
|
/* 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_set_foffset_hz
|
|
*
|
|
* Description:
|
|
* Sets the FC OFFSET register starting from frequency offset expressed in Hz.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* foffset - Frequency offset expressed in Hz as signed word.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) returned on success; a negated errno value is returned on any
|
|
* failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_foffset_hz(FAR struct spirit_library_s *spirit,
|
|
int32_t foffset)
|
|
{
|
|
uint8_t tmp[2];
|
|
int16_t offset;
|
|
|
|
/* Check that the Offset is in the correct range */
|
|
|
|
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);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_foffset
|
|
*
|
|
* Description:
|
|
* Returns the actual frequency offset.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Frequency offset expressed in Hz as signed word.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int32_t spirit_radio_get_foffset(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint16_t offtmp;
|
|
int16_t fcoffset;
|
|
uint8_t tmp[2];
|
|
|
|
/* Read the FC_OFFSET registers */
|
|
|
|
(void)spirit_reg_read(spirit, FC_OFFSET1_BASE, tmp, 2);
|
|
|
|
/* Calculates the Offset Factor */
|
|
|
|
offtmp = (((uint16_t)tmp[0] << 8) + (uint16_t)tmp[1]);
|
|
|
|
if ((offtmp & 0x0800) != 0)
|
|
{
|
|
offtmp |= 0xf000;
|
|
}
|
|
else
|
|
{
|
|
offtmp &= 0x0fff;
|
|
}
|
|
|
|
fcoffset = *((int16_t *)(&offtmp));
|
|
|
|
/* Calculates the frequency offset and return it */
|
|
|
|
return ((int32_t)(fcoffset * spirit->xtal_frequency) / FBASE_DIVIDER);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_basefrequency
|
|
*
|
|
* Description:
|
|
* Sets the Synth word and the Band Select register according to desired
|
|
* base carrier frequency. In this API the Xtal configuration is read out
|
|
* from the corresponding register. The user shall fix it before call this
|
|
* API.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* fbase - The base carrier frequency expressed in Hz as unsigned word.
|
|
*
|
|
* Returned Value:
|
|
* Error code: 0=no error, <0=error during calibration of VCO.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_basefrequency(FAR struct spirit_library_s *spirit,
|
|
uint32_t fbase)
|
|
{
|
|
int32_t foffset;
|
|
uint32_t synthword;
|
|
uint32_t chspace;
|
|
uint32_t fc;
|
|
uint8_t anaregs[4];
|
|
uint8_t refdiv;
|
|
uint8_t band;
|
|
uint8_t wcp;
|
|
uint8_t chnum;
|
|
int ret;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_FREQUENCY_BAND(fbase));
|
|
|
|
/* Search the operating band */
|
|
|
|
if (IS_FREQUENCY_BAND_HIGH(fbase))
|
|
{
|
|
band = HIGH_BAND;
|
|
}
|
|
else if (IS_FREQUENCY_BAND_MIDDLE(fbase))
|
|
{
|
|
band = MIDDLE_BAND;
|
|
}
|
|
else if (IS_FREQUENCY_BAND_LOW(fbase))
|
|
{
|
|
band = LOW_BAND;
|
|
}
|
|
else
|
|
{
|
|
band = VERY_LOW_BAND;
|
|
}
|
|
|
|
foffset = spirit_radio_get_foffset(spirit);
|
|
chspace = spirit_radio_get_chspace(spirit);
|
|
chnum = spirit_radio_get_channel(spirit);
|
|
|
|
/* Calculates the channel center frequency */
|
|
|
|
fc = fbase + foffset + chspace * chnum;
|
|
|
|
/* Read the reference divider */
|
|
|
|
refdiv = (uint8_t)spirit_radio_get_refdiv(spirit) + 1;
|
|
|
|
/* Selects the VCO */
|
|
|
|
switch (band)
|
|
{
|
|
case VERY_LOW_BAND:
|
|
if (fc < 161281250)
|
|
{
|
|
spirit_calib_select_vco(spirit, VCO_L);
|
|
}
|
|
else
|
|
{
|
|
spirit_calib_select_vco(spirit, VCO_H);
|
|
}
|
|
break;
|
|
|
|
case LOW_BAND:
|
|
if (fc < 322562500)
|
|
{
|
|
spirit_calib_select_vco(spirit, VCO_L);
|
|
}
|
|
else
|
|
{
|
|
spirit_calib_select_vco(spirit, VCO_H);
|
|
}
|
|
break;
|
|
|
|
case MIDDLE_BAND:
|
|
if (fc < 430083334)
|
|
{
|
|
spirit_calib_select_vco(spirit, VCO_L);
|
|
}
|
|
else
|
|
{
|
|
spirit_calib_select_vco(spirit, VCO_H);
|
|
}
|
|
break;
|
|
|
|
case HIGH_BAND:
|
|
if (fc < 860166667)
|
|
{
|
|
spirit_calib_select_vco(spirit, VCO_L);
|
|
}
|
|
else
|
|
{
|
|
spirit_calib_select_vco(spirit, VCO_H);
|
|
}
|
|
}
|
|
|
|
/* Search the VCO charge pump word and set the corresponding register */
|
|
|
|
wcp = spirit_radio_search_wcp(spirit, fc);
|
|
|
|
synthword = (uint32_t)(fbase * g_vectc_bhalf[band] *
|
|
(((double)(FBASE_DIVIDER * refdiv)) /
|
|
spirit->xtal_frequency));
|
|
|
|
/* Build the array of registers values for the analog part */
|
|
|
|
anaregs[0] = (uint8_t)(((synthword >> 21) & 0x0000001f) | (wcp << 5));
|
|
anaregs[1] = (uint8_t)((synthword >> 13) & 0x000000ff);
|
|
anaregs[2] = (uint8_t)((synthword >> 5) & 0x000000ff);
|
|
anaregs[3] = (uint8_t)(((synthword & 0x0000001f) << 3) | g_vectc_bandval[band]);
|
|
|
|
/* Configures the needed Analog Radio registers */
|
|
|
|
ret = spirit_reg_write(spirit, SYNT3_BASE, anaregs, 4);
|
|
if (ret < 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
/* Should be perform the VCO calibration WA? */
|
|
|
|
if (spirit->vcocalib == S_ENABLE)
|
|
{
|
|
return spirit_managment_wavco_calibration(spirit);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_wavco_calibration
|
|
*
|
|
* Description:
|
|
* Enable/disabe the VCO calibration WA at the end of
|
|
* spirit_radio_set_basefrequency()
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* S_ENABLE or S_DISABLE the WA procedure.
|
|
*
|
|
* Returned Value:
|
|
* None.
|
|
*
|
|
******************************************************************************/
|
|
|
|
void spirit_radio_enable_wavco_calibration(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
spirit->vcocalib = newstate;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_basefrequency
|
|
*
|
|
* Description:
|
|
* Returns the base carrier frequency.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Base carrier frequency expressed in Hz as unsigned word.
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint32_t spirit_radio_get_basefrequency(FAR struct spirit_library_s *spirit)
|
|
{
|
|
enum spirit_bandselect_e band;
|
|
uint32_t synthword;
|
|
uint8_t refdiv;
|
|
|
|
/* Read the synth word */
|
|
|
|
synthword = spirit_radio_get_synthword(spirit);
|
|
|
|
/* Read the operating band */
|
|
|
|
band = spirit_radio_get_band(spirit);
|
|
|
|
refdiv = (uint8_t)spirit_radio_get_refdiv(spirit) + 1;
|
|
|
|
/* Calculates the frequency base and return it */
|
|
|
|
return (uint32_t) round(synthword * (((double)spirit->xtal_frequency) /
|
|
(FBASE_DIVIDER * refdiv *
|
|
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
|
|
*
|
|
* Description:
|
|
* Returns the mantissa and exponent, whose value used in the datarate
|
|
* formula will give the datarate value closer to the given datarate.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* datarate - datarate expressed in bps. This parameter ranging between 100 and 500000.
|
|
* 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_datarate(FAR struct spirit_library_s *spirit,
|
|
uint32_t datarate, FAR uint8_t *pcm,
|
|
FAR uint8_t *pce)
|
|
{
|
|
int16_t intermediate[3];
|
|
uint16_t delta;
|
|
uint8_t mantissa;
|
|
uint8_t divider = 0;
|
|
int8_t i = 15;
|
|
uint8_t j;
|
|
volatile bool find = false;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_DATARATE(datarate));
|
|
|
|
divider = (uint8_t)spirit_radio_isenabled_digdivider(spirit);
|
|
|
|
/* Search in the datarate array the exponent value */
|
|
|
|
while (!find && i >= 0)
|
|
{
|
|
if (datarate >= (spirit->xtal_frequency >> (20 - i + divider)))
|
|
{
|
|
find = true;
|
|
}
|
|
else
|
|
{
|
|
i--;
|
|
}
|
|
}
|
|
|
|
i < 0 ? i = 0 : i;
|
|
*pce = i;
|
|
|
|
/* Calculates the mantissa value according to the datarate formula */
|
|
|
|
mantissa = (datarate * ((uint32_t)1 << (23 - i))) /
|
|
(spirit->xtal_frequency >> (5 + divider)) - 256;
|
|
|
|
/* Finds the mantissa value with less approximation */
|
|
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
if ((mantissa + j - 1))
|
|
{
|
|
intermediate[j] = datarate - (((256 + mantissa + j - 1) *
|
|
(spirit->xtal_frequency >> (5 + divider))) >>
|
|
(23 - i));
|
|
}
|
|
else
|
|
{
|
|
intermediate[j] = 0x7fff;
|
|
}
|
|
}
|
|
|
|
delta = 0xffff;
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
if (S_ABS(intermediate[j]) < delta)
|
|
{
|
|
delta = S_ABS(intermediate[j]);
|
|
*pcm = mantissa + j - 1;
|
|
}
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* 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)
|
|
{
|
|
uint32_t chfltfactor;
|
|
int16_t intermediate[3];
|
|
uint16_t delta;
|
|
uint8_t divider = 1;
|
|
int8_t tmp;
|
|
int8_t i;
|
|
int8_t j;
|
|
|
|
/* Search in the channel filter bandwidth table the exponent value */
|
|
|
|
if (spirit_radio_isenabled_digdivider(spirit) != S_DISABLE)
|
|
{
|
|
divider = 2;
|
|
}
|
|
else
|
|
{
|
|
divider = 1;
|
|
}
|
|
|
|
DEBUGASSERT(IS_CH_BW(bandwidth, spirit->xtal_frequency / divider));
|
|
|
|
chfltfactor = (spirit->xtal_frequency / divider) / 100;
|
|
|
|
for (i = 0;
|
|
i < 90 && (bandwidth < (uint32_t)((g_vectn_bandwidth[i] *
|
|
chfltfactor) / 2600));
|
|
i++);
|
|
|
|
if (i != 0)
|
|
{
|
|
/* Finds the mantissa value with less approximation */
|
|
|
|
tmp = i;
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
if (((tmp + j - 1) >= 0) || ((tmp + j - 1) <= 89))
|
|
{
|
|
intermediate[j] = bandwidth -
|
|
(uint32_t)((g_vectn_bandwidth[tmp + j - 1] *
|
|
chfltfactor) / 2600);
|
|
}
|
|
else
|
|
{
|
|
intermediate[j] = 0x7fff;
|
|
}
|
|
}
|
|
|
|
delta = 0xFFFF;
|
|
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
if (S_ABS(intermediate[j]) < delta)
|
|
{
|
|
delta = S_ABS(intermediate[j]);
|
|
i = tmp + j - 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
*pce = (uint8_t)(i / 9);
|
|
*pcm = (uint8_t)(i % 9);
|
|
return OK;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* 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.
|
|
*
|
|
* 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.
|
|
* power - Desired power in dBm.
|
|
*
|
|
* Returned Value:
|
|
* Register value as byte.
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_convert_power2reg(FAR struct spirit_library_s *spirit,
|
|
uint32_t fbase, float power)
|
|
{
|
|
float pavalue;
|
|
uint8_t i = 0;
|
|
uint8_t j = 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 (power > 0 &&
|
|
13.0 / g_power_factors[i][2] - g_power_factors[i][3] /
|
|
g_power_factors[i][2] < power)
|
|
{
|
|
j = 0;
|
|
}
|
|
else if (power <= 0 &&
|
|
40.0 / g_power_factors[i][2] - g_power_factors[i][3] /
|
|
g_power_factors[i][2] > power)
|
|
{
|
|
j = 2;
|
|
}
|
|
|
|
pavalue = g_power_factors[i][2 * j] * power +
|
|
g_power_factors[i][2 * j + 1];
|
|
|
|
if (pavalue < 1)
|
|
{
|
|
pavalue = 1;
|
|
}
|
|
else if (pavalue > 90)
|
|
{
|
|
pavalue = 90;
|
|
}
|
|
|
|
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_dbm
|
|
*
|
|
* 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_dbm(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: spirit_radio_get_patable_dbm
|
|
*
|
|
* 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_dbm(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_dbm
|
|
*
|
|
* Description:
|
|
* Sets a specific PA_LEVEL register, with a value given in dBm.
|
|
*
|
|
* 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].
|
|
* 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.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_palevel_dbm(FAR struct spirit_library_s *spirit,
|
|
uint8_t ndx, float power)
|
|
{
|
|
uint32_t basefrequency;
|
|
uint8_t address;
|
|
uint8_t level;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_PA_MAX_INDEX(ndx));
|
|
DEBUGASSERT(IS_PAPOWER_DBM(power));
|
|
|
|
/* Interpolate the power level */
|
|
|
|
basefrequency = spirit_radio_get_basefrequency(spirit);
|
|
level = spirit_radio_convert_power2reg(spirit, basefrequency, power);
|
|
|
|
/* Sets the base address */
|
|
|
|
address = PA_POWER8_BASE + 7 - ndx;
|
|
|
|
/* Configures the PA_LEVEL register */
|
|
|
|
return spirit_reg_write(spirit, address, &level, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_palevel_dbm
|
|
*
|
|
* Description:
|
|
* Returns a specific PA_LEVEL register, returning a value in dBm.
|
|
*
|
|
* NOTE: This function makes use of the @ref spirit_radio_convert_reg2power fcn to
|
|
* interpolate the power value.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* ndx - PA_LEVEL to read. This parameter shall be in the range [0:7]
|
|
*
|
|
* Returned Value:
|
|
* Settled power level expressed in dBm. A value higher than PA_UPPER_LIMIT
|
|
* dBm implies no output power (output stage is in high impedance).
|
|
*
|
|
******************************************************************************/
|
|
|
|
float spirit_radio_get_palevel_dbm(FAR struct spirit_library_s *spirit,
|
|
uint8_t ndx)
|
|
{
|
|
uint8_t regaddr;
|
|
uint8_t value;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_PA_MAX_INDEX(ndx));
|
|
|
|
/* Sets the base address */
|
|
|
|
regaddr = PA_POWER8_BASE + 7 - ndx;
|
|
|
|
/* Reads the PA_LEVEL[ndx] register */
|
|
|
|
(void)spirit_reg_read(spirit, regaddr, &value, 1);
|
|
|
|
return spirit_radio_convert_reg2power(spirit,
|
|
spirit_radio_get_basefrequency(spirit),
|
|
value);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_config_patable
|
|
*
|
|
* Description:
|
|
* Configures the Power Amplifier Table and registers.
|
|
*
|
|
* 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 - One of the possible value of the enum type enum
|
|
* spirit_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 the range [0: 90], where
|
|
* 0 implies no output power, 1 will be the maximum level and 90
|
|
* the minimum one. 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 uint8_t *table)
|
|
{
|
|
uint8_t palevel[9];
|
|
uint8_t regaddr;
|
|
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 levels are in the range */
|
|
|
|
for (i = 0; i <= nlevels; i++)
|
|
{
|
|
DEBUGASSERT(IS_PAPOWER(*table));
|
|
palevel[nlevels - i] = *table;
|
|
table++;
|
|
}
|
|
|
|
/* Sets the PA_POWER[0] register */
|
|
|
|
palevel[nlevels + 1] = load | ((width - 1) << 3) | nlevels;
|
|
|
|
/* Sets the base address */
|
|
|
|
regaddr = PA_POWER8_BASE + 7 - nlevels;
|
|
|
|
/* Configures the PA_POWER registers */
|
|
|
|
return spirit_reg_write(spirit, regaddr, palevel, nlevels + 2);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_patable
|
|
*
|
|
* Description:
|
|
* Returns the Power Amplifier Table and registers.
|
|
*
|
|
* 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. The
|
|
* first element will be the PA_LEVEL_0 and the last element will
|
|
* be PA_LEVEL_7. Any value equals to 0 implies that level has 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 uint8_t *table)
|
|
{
|
|
uint8_t palevels[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, palevels, 9);
|
|
if (ret >= 0)
|
|
{
|
|
/* Fill the PAtable */
|
|
|
|
for (i = 7; i >= 0; i--)
|
|
{
|
|
*table++ = palevels[i];
|
|
}
|
|
|
|
/* Return the settled index */
|
|
|
|
*nlevels = palevels[8] & 0x07;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_palevel
|
|
*
|
|
* Description:
|
|
* Sets a specific PA_LEVEL register.
|
|
*
|
|
* 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].
|
|
* power - PA value to write in the register. Be sure that this values is
|
|
* in the correct range [0 : 90].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_palevel(FAR struct spirit_library_s *spirit,
|
|
uint8_t ndx, uint8_t power)
|
|
{
|
|
uint8_t regaddr;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_PA_MAX_INDEX(ndx));
|
|
DEBUGASSERT(IS_PAPOWER(power));
|
|
|
|
/* Sets the base address */
|
|
|
|
regaddr = PA_POWER8_BASE + 7 - ndx;
|
|
|
|
/* Configures the PA_LEVEL register */
|
|
|
|
return spirit_reg_write(spirit, regaddr, &power, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_palevel
|
|
*
|
|
* Description:
|
|
* Returns a specific PA_LEVEL register.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* ndx - PA_LEVEL to read. This parameter shall be in the range [0:7].
|
|
*
|
|
* Returned Value:
|
|
* PA_LEVEL value. A value equal to zero
|
|
* implies no output power (output stage is in high impedance).
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_palevel(FAR struct spirit_library_s *spirit,
|
|
uint8_t ndx)
|
|
{
|
|
uint8_t regaddr;
|
|
uint8_t regval;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_PA_MAX_INDEX(ndx));
|
|
|
|
/* Sets the base address */
|
|
|
|
regaddr = PA_POWER8_BASE + 7 - ndx;
|
|
|
|
/* Reads the PA_LEVEL[ndx] register and return the value */
|
|
|
|
(void)spirit_reg_read(spirit, regaddr, ®val, 1);
|
|
return regval;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_outputload
|
|
*
|
|
* Description:
|
|
* Sets the output stage additional load capacitor bank.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* load one of the possible value of the enum type enum spirit_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
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_outputload(FAR struct spirit_library_s *spirit,
|
|
enum spirit_paload_capacitor_e load)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_PA_LOAD_CAP(load));
|
|
|
|
/* Read the PA_POWER_0 register */
|
|
|
|
ret = spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Mask the CWC[1:0] field and write the new value */
|
|
|
|
regval &= 0x3f;
|
|
regval |= load;
|
|
|
|
/* Configures the PA_POWER_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, PA_POWER0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_outputload
|
|
*
|
|
* Description:
|
|
* Returns the output stage additional load capacitor bank.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Output stage additional load capacitor bank. This value may be:
|
|
*
|
|
* 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
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_paload_capacitor_e
|
|
spirit_radio_get_outputload(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the PA_POWER_0 register */
|
|
|
|
(void)spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1);
|
|
|
|
/* Mask the CWC[1:0] field and return the value */
|
|
|
|
return (enum spirit_paload_capacitor_e)(regval & 0xc0);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_palevel_maxindex
|
|
*
|
|
* Description:
|
|
* Sets a specific PA_LEVEL_MAX_INDEX.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* ndx - PA_LEVEL_MAX_INDEX to set. This parameter must be in the range
|
|
* [0:7].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_palevel_maxindex(FAR struct spirit_library_s *spirit,
|
|
uint8_t ndx)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_PA_MAX_INDEX(ndx));
|
|
|
|
/* Read the PA_POWER_0 register */
|
|
|
|
ret = spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Mask the PA_LEVEL_MAX_INDEX[1:0] field and write the new value */
|
|
|
|
regval &= 0xf8;
|
|
regval |= ndx;
|
|
|
|
/* Configures the PA_POWER_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, PA_POWER0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_palevel_maxindex
|
|
*
|
|
* Description:
|
|
* Returns the actual PA_LEVEL_MAX_INDEX.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Actual PA_LEVEL_MAX_INDEX. This value will be in the range [0:7].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_palevel_maxindex(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the PA_POWER_0 register */
|
|
|
|
(void)spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1);
|
|
|
|
/* Mask the PA_LEVEL_MAX_INDEX[1:0] field and return the value */
|
|
|
|
return (regval & 0x07);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_pastep_width
|
|
*
|
|
* Description:
|
|
* Sets a specific PA_RAMP_STEP_WIDTH.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* width - Step width expressed in terms of bit period units Tb/8. This
|
|
* value must be in the range [1:4].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_pastep_width(FAR struct spirit_library_s *spirit,
|
|
uint8_t width)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_PA_STEP_WIDTH(width));
|
|
|
|
/* Read the PA_POWER_0 register */
|
|
|
|
ret = spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Mask the PA_RAMP_STEP_WIDTH[1:0] field and write the new value */
|
|
|
|
regval &= 0xe7;
|
|
regval |= (width - 1) << 3;
|
|
|
|
/* Configures the PA_POWER_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, PA_POWER0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_pastep_width
|
|
*
|
|
* Description:
|
|
* Returns the actual PA_RAMP_STEP_WIDTH.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Step width value expressed in terms of bit period units Tb/8. This
|
|
* value will be in the range [1:4].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_pastep_width(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the PA_POWER_0 register */
|
|
|
|
(void)spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1);
|
|
|
|
/* Mask the PA_RAMP_STEP_WIDTH[1:0] field and return the value */
|
|
|
|
regval &= 0x18;
|
|
return ((regval >> 3) + 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_paramp
|
|
*
|
|
* Description:
|
|
* Enables or Disables the Power Ramping.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for power ramping. This value can be: S_ENABLE
|
|
* or S_DISABLE.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_enable_paramp(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Read the PA_POWER_0 register and configure the PA_RAMP_ENABLE field */
|
|
|
|
ret = spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= PA_POWER0_PA_RAMP_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~PA_POWER0_PA_RAMP_MASK);
|
|
}
|
|
|
|
/* Set the PA_POWER_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, PA_POWER0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_isenabled_paramp
|
|
*
|
|
* Description:
|
|
* Returns the state of the Power Ramping enable bit.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for power ramping. This value can be: S_ENABLE
|
|
* or S_DISABLE.
|
|
*
|
|
* Returned Value:
|
|
* Power Ramping enable state.
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_functional_state_e
|
|
spirit_radio_isenabled_paramp(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the PA_POWER_0 register and configure the PA_RAMP_ENABLE field */
|
|
|
|
(void)spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1);
|
|
|
|
/* Mask and return data */
|
|
|
|
return (enum spirit_functional_state_e)((regval >> 5) & 0x01);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_afc
|
|
*
|
|
* Description:
|
|
* Enables or Disables the AFC.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for AFC. This value can be: S_ENABLE or
|
|
* S_DISABLE.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_enable_afc(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Read the AFC_2 register and configure the AFC Enabled field */
|
|
|
|
ret = spirit_reg_read(spirit, AFC2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= AFC2_AFC_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~AFC2_AFC_MASK);
|
|
}
|
|
|
|
/* Set the AFC_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AFC2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_afcfreezeonsync
|
|
*
|
|
* Description:
|
|
* Enables or Disables the AFC freeze on sync word detection.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - new state for AFC freeze on sync word detection.
|
|
* This parameter can be: S_ENABLE or S_DISABLE.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_afcfreezeonsync(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* 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)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= AFC2_AFC_FREEZE_ON_SYNC_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~AFC2_AFC_FREEZE_ON_SYNC_MASK);
|
|
}
|
|
|
|
/* Sets the AFC_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AFC2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_afcmode
|
|
*
|
|
* Description:
|
|
* Sets the AFC working mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* mode - The AFC mode. This value can be one of the values defined in
|
|
* enum spirit_afcmode_e:
|
|
*
|
|
* AFC_SLICER_CORRECTION AFC loop closed on slicer
|
|
* AFC_2ND_IF_CORRECTION AFC loop closed on 2nd conversion stage
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_afcmode(FAR struct spirit_library_s *spirit,
|
|
enum spirit_afcmode_e mode)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_AFC_MODE(mode));
|
|
|
|
/* Read the AFC_2 register and configure the AFC Mode field */
|
|
|
|
ret = spirit_reg_read(spirit, AFC2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (mode == AFC_2ND_IF_CORRECTION)
|
|
{
|
|
regval |= AFC_2ND_IF_CORRECTION;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~AFC_2ND_IF_CORRECTION);
|
|
}
|
|
|
|
/* Set the AFC_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AFC2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_afcmode
|
|
*
|
|
* Description:
|
|
* Returns the AFC working mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Settled AFC mode. This value will be one of the values defined in
|
|
* enum spirit_afcmode_e:
|
|
*
|
|
* AFC_SLICER_CORRECTION AFC loop closed on slicer
|
|
* AFC_2ND_IF_CORRECTION AFC loop closed on 2nd conversion stage
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_afcmode_e
|
|
spirit_radio_get_afcmode(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AFC_2 register */
|
|
|
|
(void)spirit_reg_read(spirit, AFC2_BASE, ®val, 1);
|
|
|
|
/* Mask the AFC Mode field and returns the value */
|
|
|
|
return (enum spirit_afcmode_e)(regval & 0x20);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_afcpdleakage
|
|
*
|
|
* Description:
|
|
* Sets the AFC peak detector leakage.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* leakage - The peak detector leakage. This value must be in the
|
|
* range: [0:31].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_afcpdleakage(FAR struct spirit_library_s *spirit,
|
|
uint8_t leakage)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_AFC_PD_LEAKAGE(leakage));
|
|
|
|
/* Read the AFC_2 register and configure the AFC PD leakage field */
|
|
|
|
ret = spirit_reg_read(spirit, AFC2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
regval &= 0xe0;
|
|
regval |= leakage;
|
|
|
|
/* Set the AFC_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AFC2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_afcpdleakage
|
|
*
|
|
* Description:
|
|
* Returns the AFC peak detector leakage.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Peak detector leakage value. This value will be in the range: [0:31].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_afcpdleakage(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AFC_2 register */
|
|
|
|
(void)spirit_reg_read(spirit, AFC2_BASE, ®val, 1);
|
|
|
|
/* Mask the AFC PD leakage field and return the value */
|
|
|
|
return (regval & 0x1f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_afcfastperiod
|
|
*
|
|
* Description:
|
|
* Sets the length of the AFC fast period expressed as number of samples.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* length - Length of the fast period in number of samples.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_afcfastperiod(FAR struct spirit_library_s *spirit,
|
|
uint8_t length)
|
|
{
|
|
/* Set the AFC_1 register */
|
|
|
|
return spirit_reg_write(spirit, AFC1_BASE, &length, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_afcfastperiod
|
|
*
|
|
* Description:
|
|
* Returns the AFC fast period expressed as number of samples.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Length of the fast period in number of samples.
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_afcfastperiod(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AFC 1 register and return the value */
|
|
|
|
(void)spirit_reg_read(spirit, AFC1_BASE, ®val, 1);
|
|
|
|
return regval;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_afcfastgain
|
|
*
|
|
* Description:
|
|
* Sets the AFC loop gain in fast mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* gain - AFC loop gain in fast mode. This value must be in the range:
|
|
* [0:15].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_afcfastgain(FAR struct spirit_library_s *spirit,
|
|
uint8_t gain)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_AFC_FAST_GAIN(gain));
|
|
|
|
/* Read the AFC_0 register and configure the AFC Fast Gain field */
|
|
|
|
ret = spirit_reg_read(spirit, AFC0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
regval &= 0x0f;
|
|
regval |= gain << 4;
|
|
|
|
/* Set the AFC_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, AFC0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_afcfastgain
|
|
*
|
|
* Description:
|
|
* Returns the AFC loop gain in fast mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* uint8_t AFC loop gain in fast mode. This value will be in the range:
|
|
* [0:15].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_afcfastgain(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AFC_0 register, mask the AFC Fast Gain field and return the
|
|
* value.
|
|
*/
|
|
|
|
(void)spirit_reg_read(spirit, AFC0_BASE, ®val, 1);
|
|
|
|
return ((regval & 0xf0) >> 4);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_afclowgain
|
|
*
|
|
* Description:
|
|
* Sets the AFC loop gain in slow mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* gain - AFC loop gain in slow mode. This value must be in the range:
|
|
* [0:15].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_afclowgain(FAR struct spirit_library_s *spirit,
|
|
uint8_t gain)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_AFC_SLOW_GAIN(gain));
|
|
|
|
/* Read the AFC_0 register and configure the AFC Slow Gain field */
|
|
|
|
ret = spirit_reg_read(spirit, AFC0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
regval &= 0xf0;
|
|
regval |= gain;
|
|
|
|
/* Set the AFC_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, AFC0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_afclowgain
|
|
*
|
|
* Description:
|
|
* Returns the AFC loop gain in slow mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AFC loop gain in slow mode. This value will be in the range: [0:15].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_afclowgain(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AFC_0 register, mask the AFC Slow Gain field and return the
|
|
* value */
|
|
|
|
(void)spirit_reg_read(spirit, AFC0_BASE, ®val, 1);
|
|
|
|
return (regval & 0x0f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_afccorrection
|
|
*
|
|
* Description:
|
|
* Returns the AFC correction from the corresponding register.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AFC correction, read from the corresponding register. This value
|
|
* will be in the range [-128:127].
|
|
*
|
|
******************************************************************************/
|
|
|
|
int8_t spirit_radio_get_afccorrection(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AFC_CORR register, cast the read value as signed char and return
|
|
* it.
|
|
*/
|
|
|
|
(void)spirit_reg_read(spirit, AFC_CORR_BASE, ®val, 1);
|
|
|
|
return (int8_t)regval;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_afccorrection_hz
|
|
*
|
|
* Description:
|
|
* Returns the AFC correction expressed in Hz.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AFC correction expressed in Hz according to the following formula:
|
|
*
|
|
* Fafc[Hz]= (Fdig/(12*2^10))*AFC_CORR
|
|
*
|
|
* where AFC_CORR is the value read in the AFC_CORR register
|
|
*
|
|
******************************************************************************/
|
|
|
|
int32_t spirit_radio_get_afccorrection_hz(FAR struct spirit_library_s *spirit)
|
|
{
|
|
int8_t correction;
|
|
uint32_t xtal = spirit->xtal_frequency;
|
|
|
|
/* Read the AFC correction register */
|
|
|
|
correction = spirit_radio_get_afccorrection(spirit);
|
|
|
|
if (xtal > DOUBLE_XTAL_THR)
|
|
{
|
|
xtal /= 2;
|
|
}
|
|
|
|
/* Calculates and return the Frequency Correction */
|
|
|
|
return (int32_t)(xtal / (12 * pow(2, 10)) * correction);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_agc
|
|
*
|
|
* Description:
|
|
* Enables or Disables the AGC.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for AGC.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_enable_agc(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Read the AGCCTRL_0 register and configure the AGC Enabled field */
|
|
|
|
ret = spirit_reg_read(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= AGCCTRL0_AGC_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~AGCCTRL0_AGC_MASK);
|
|
}
|
|
|
|
/* Set the AGCCTRL_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_agcmode
|
|
*
|
|
* Description:
|
|
* Sets the AGC working mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* mode - The AGC mode. This value can be one of the values defined in
|
|
* enum spirit_agcmode_e:
|
|
*
|
|
* AGC_LINEAR_MODE AGC works in linear mode
|
|
* AGC_BINARY_MODE AGC works in binary mode
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_agcmode(FAR struct spirit_library_s *spirit,
|
|
enum spirit_agcmode_e mode)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_AGC_MODE(mode));
|
|
|
|
/* Read the AGCCTRL_0 register and configure the AGC Mode field */
|
|
|
|
ret = spirit_reg_read(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (mode == AGC_BINARY_MODE)
|
|
{
|
|
regval |= AGC_BINARY_MODE;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~AGC_BINARY_MODE);
|
|
}
|
|
|
|
/* Set the AGCCTRL_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_agcmode
|
|
*
|
|
* Description:
|
|
* Returns the AGC working mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Settled AGC mode. This value can be one of the values defined in
|
|
* enum spirit_agcmode_e:
|
|
*
|
|
* AGC_LINEAR_MODE AGC works in linear mode
|
|
* AGC_BINARY_MODE AGC works in binary mode
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_agcmode_e
|
|
spirit_radio_get_agcmode(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AGCCTRL_0 register, mask the AGC Mode field and return the value */
|
|
|
|
(void)spirit_reg_read(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
|
|
return (enum spirit_agcmode_e)(regval & 0x40);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_agcfreeze_steady
|
|
*
|
|
* Description:
|
|
* Enables or Disables the AGC freeze on steady state.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for AGC freeze on steady state.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_enable_agcfreeze_steady(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Read the AGCCTRL_2 register and configure the AGC Freeze On Steady field */
|
|
|
|
ret = spirit_reg_read(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= AGCCTRL2_FREEZE_ON_STEADY_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~AGCCTRL2_FREEZE_ON_STEADY_MASK);
|
|
}
|
|
|
|
/* Set the AGCCTRL_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_agcfreeze_sync
|
|
*
|
|
* Description:
|
|
* Enable or Disable the AGC freeze on sync detection.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for AGC freeze on sync detection.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_enable_agcfreeze_sync(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Read the AGCCTRL_2 register and configure the AGC Freeze On Sync field */
|
|
|
|
ret = spirit_reg_read(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= AGCCTRL2_FREEZE_ON_SYNC_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~AGCCTRL2_FREEZE_ON_SYNC_MASK);
|
|
}
|
|
|
|
/* Set the AGCCTRL_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_agcfreeze_maxatten
|
|
*
|
|
* Description:
|
|
* Enable or Disable the AGC to start with max attenuation.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for AGC start with max attenuation mode.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_enable_agcfreeze_maxatten(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Read the AGCCTRL_2 register and configure the AGC Start Max Attenuation
|
|
* field */
|
|
|
|
ret = spirit_reg_read(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= AGCCTRL2_START_MAX_ATTENUATION_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~AGCCTRL2_START_MAX_ATTENUATION_MASK);
|
|
}
|
|
|
|
/* Set the AGCCTRL_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_agcmeasure_us
|
|
*
|
|
* Description:
|
|
* Sets the AGC measure time.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* time - AGC measure time expressed in us. This value must be in the
|
|
* range [0, 393216/F_Xo].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_agcmeasure_us(FAR struct spirit_library_s *spirit,
|
|
uint16_t time)
|
|
{
|
|
uint8_t regval;
|
|
uint8_t measure;
|
|
int ret;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_AGC_MEASURE_TIME_US(time, spirit->xtal_frequency));
|
|
|
|
/* Read the AGCCTRL_2 register */
|
|
|
|
ret = spirit_reg_read(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Calculates the measure time value to write in the register */
|
|
|
|
measure = (uint8_t)
|
|
lroundf(log2((float)time / 1e6 * spirit->xtal_frequency / 12));
|
|
|
|
if (measure > 15)
|
|
{
|
|
measure = 15;
|
|
}
|
|
|
|
/* Mask the MEAS_TIME field and write the new value */
|
|
|
|
regval &= 0xf0;
|
|
regval |= measure;
|
|
|
|
/* Set the AGCCTRL_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_agcmeasure_us
|
|
*
|
|
* Description:
|
|
* Returns the AGC measure time in microseconds.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AGC measure time expressed in microseconds. This value will be in
|
|
* the range [0, 393216/Fxo].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint16_t spirit_radio_get_agcmeasure_us(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t measure;
|
|
|
|
/* Read the AGCCTRL_2 register */
|
|
|
|
(void)spirit_reg_read(spirit, AGCCTRL2_BASE, &measure, 1);
|
|
|
|
/* Mask the MEAS_TIME field */
|
|
|
|
measure &= 0x0f;
|
|
|
|
/* Calculates the measure time value to write in the register */
|
|
|
|
return (uint16_t)((12.0 / spirit->xtal_frequency) * (float)pow(2, measure) * 1e6);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_agcmeasure
|
|
*
|
|
* Description:
|
|
* Sets the AGC measure time.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* time - AGC measure time to write in the MEAS_TIME field of AGCCTRL_2
|
|
* register. This value must be in the range [0:15].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_agcmeasure(FAR struct spirit_library_s *spirit,
|
|
uint8_t time)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_AGC_MEASURE_TIME(time));
|
|
|
|
/* Read the AGCCTRL_2 register */
|
|
|
|
ret = spirit_reg_read(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Mask the MEAS_TIME field and write the new value */
|
|
|
|
regval &= 0xf0;
|
|
regval |= time;
|
|
|
|
/* Set the AGCCTRL_2 register */
|
|
|
|
ret = spirit_reg_write(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_agcmeasure
|
|
*
|
|
* Description:
|
|
* Returns the AGC measure time.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AGC measure time read from the MEAS_TIME field of AGCCTRL_2 register.
|
|
* This value will be in the range [0:15].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_agcmeasure(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AGCCTRL_2 register, mask the MEAS_TIME field and return the
|
|
* value.
|
|
*/
|
|
|
|
(void)spirit_reg_read(spirit, AGCCTRL2_BASE, ®val, 1);
|
|
|
|
return (regval & 0x0f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_agcholdtime_us
|
|
*
|
|
* Description:
|
|
* Sets the AGC hold time.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* time - AGC hold time expressed in us. This value must be in the
|
|
* range [0, 756/F_Xo].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_agcholdtime_us(FAR struct spirit_library_s *spirit,
|
|
uint8_t time)
|
|
{
|
|
uint8_t regval, hold;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_AGC_HOLD_TIME_US(time, spirit->xtal_frequency));
|
|
|
|
/* Read the AGCCTRL_0 register */
|
|
|
|
spirit_reg_read(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
|
|
/* Calculates the hold time value to write in the register */
|
|
|
|
hold = (uint8_t) lroundf(((float)time / 1e6 * spirit->xtal_frequency) / 12);
|
|
(hold > 63) ? (hold = 63) : (hold);
|
|
|
|
/* Mask the HOLD_TIME field and write the new value */
|
|
|
|
regval &= 0xc0;
|
|
regval |= hold;
|
|
|
|
/* Set the AGCCTRL_0 register */
|
|
|
|
return spirit_reg_write(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_agcholdtime_us
|
|
*
|
|
* Description:
|
|
* Returns the AGC hold time.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AGC hold time expressed in us. This value will be in the range:
|
|
* [0, 756/F_Xo].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_agcholdtime_us(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AGCCTRL_0 register */
|
|
|
|
(void)spirit_reg_read(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
|
|
/* Mask the HOLD_TIME field */
|
|
|
|
regval &= 0x3f;
|
|
|
|
/* Calculates the hold time value and return it */
|
|
|
|
return (uint8_t) lroundf((12.0 / spirit->xtal_frequency) * (regval * 1e6));
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_agcholdtime
|
|
*
|
|
* Description:
|
|
* Sets the AGC hold time.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* time - AGC hold time to write in the HOLD_TIME field of AGCCTRL_0
|
|
* register. This value must be in the range [0:63].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_agcholdtime(FAR struct spirit_library_s *spirit,
|
|
uint8_t time)
|
|
{
|
|
uint8_t regval;
|
|
int ret;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_AGC_HOLD_TIME(time));
|
|
|
|
/* Read the AGCCTRL_0 register */
|
|
|
|
ret = spirit_reg_read(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
/* Mask the HOLD_TIME field and write the new value */
|
|
|
|
regval &= 0xc0;
|
|
regval |= time;
|
|
|
|
/* Set the AGCCTRL_0 register */
|
|
|
|
ret = spirit_reg_write(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_agcholdtime
|
|
*
|
|
* Description:
|
|
* Returns the AGC hold time.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AGC hold time read from the HOLD_TIME field of AGCCTRL_0 register. This
|
|
* value will be in the range [0:63].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_agcholdtime(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AGCCTRL_0 register, mask the MEAS_TIME field and return the
|
|
* value.
|
|
*/
|
|
|
|
(void)spirit_reg_read(spirit, AGCCTRL0_BASE, ®val, 1);
|
|
|
|
return (regval & 0x3f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_agchighthres
|
|
*
|
|
* Description:
|
|
* Sets the AGC high threshold.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* highthres - AGC high threshold to write in the THRESHOLD_HIGH field of
|
|
* AGCCTRL_1 register. This value must be in the range
|
|
* [0:15].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_agchighthres(FAR struct spirit_library_s *spirit,
|
|
uint8_t highthres)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_AGC_THRESHOLD(highthres));
|
|
|
|
/* Read the AGCCTRL_1 register */
|
|
|
|
spirit_reg_read(spirit, AGCCTRL1_BASE, ®val, 1);
|
|
|
|
/* Mask the THRESHOLD_HIGH field and write the new value */
|
|
|
|
regval &= 0x0f;
|
|
regval |= highthres << 4;
|
|
|
|
/* Set the AGCCTRL_1 register */
|
|
|
|
return spirit_reg_write(spirit, AGCCTRL1_BASE, ®val, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_agchighthres
|
|
*
|
|
* Description:
|
|
* Returns the AGC high threshold.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AGC high threshold read from the THRESHOLD_HIGH field of AGCCTRL_1
|
|
* register. This value will be in the range [0:15].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_agchighthres(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AGCCTRL_1 register, mask the THRESHOLD_HIGH field and return the
|
|
* value */
|
|
|
|
(void)spirit_reg_read(spirit, AGCCTRL1_BASE, ®val, 1);
|
|
|
|
return ((regval & 0xf0) >> 4);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_agclowthres
|
|
*
|
|
* Description:
|
|
* Sets the AGC low threshold.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* lowthres - AGC low threshold to write in the THRESHOLD_LOW field of
|
|
* AGCCTRL_1 register. This value must be in the range
|
|
* 0:15].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_agclowthres(FAR struct spirit_library_s *spirit,
|
|
uint8_t lowthres)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_AGC_THRESHOLD(lowthres));
|
|
|
|
/* Read the AGCCTRL_1 register */
|
|
|
|
spirit_reg_read(spirit, AGCCTRL1_BASE, ®val, 1);
|
|
|
|
/* Mask the THRESHOLD_LOW field and write the new value */
|
|
|
|
regval &= 0xf0;
|
|
regval |= lowthres;
|
|
|
|
/* Set the AGCCTRL_1 register */
|
|
|
|
return spirit_reg_write(spirit, AGCCTRL1_BASE, ®val, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_agclowthres
|
|
*
|
|
* Description:
|
|
* Returns the AGC low threshold.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* AGC low threshold read from the THRESHOLD_LOW field of AGCCTRL_1 register.
|
|
* This value will be in the range [0:15].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_agclowthres(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the AGCCTRL_1 register, mask the THRESHOLD_LOW field and return the
|
|
* value */
|
|
|
|
(void)spirit_reg_read(spirit, AGCCTRL1_BASE, ®val, 1);
|
|
|
|
return (regval & 0x0f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_clkrecmode
|
|
*
|
|
* Description:
|
|
* Sets the clock recovery algorithm.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* mode - The Clock Recovery mode. This value can be one of the values
|
|
* defined in enum spirit_clkrecmode_e :
|
|
*
|
|
* CLK_REC_PLL PLL alogrithm for clock recovery
|
|
* CLK_REC_DLL DLL alogrithm for clock recovery
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_clkrecmode(FAR struct spirit_library_s *spirit,
|
|
enum spirit_clkrecmode_e mode)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_CLK_REC_MODE(mode));
|
|
|
|
/* Read the FDEV_0 register */
|
|
|
|
spirit_reg_read(spirit, FDEV0_BASE, ®val, 1);
|
|
|
|
/* Mask the CLOCK_REC_ALGO_SEL field and write the new value */
|
|
|
|
regval &= 0xf7;
|
|
regval |= (uint8_t) mode;
|
|
|
|
/* Set the FDEV_0 register */
|
|
|
|
return spirit_reg_write(spirit, FDEV0_BASE, ®val, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_clkrecmode
|
|
*
|
|
* Description:
|
|
* Returns the Clock Recovery working mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Clock Recovery mode. This value can be one of the values defined in
|
|
* enum spirit_clkrecmode_e:
|
|
*
|
|
* CLK_REC_PLL PLL alogrithm for clock recovery
|
|
* CLK_REC_DLL DLL alogrithm for clock recovery
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_clkrecmode_e
|
|
spirit_radio_get_clkrecmode(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the FDEV_0 register, mask the CLOCK_REC_ALGO_SEL field and return
|
|
* the value */
|
|
|
|
(void)spirit_reg_read(spirit, FDEV0_BASE, ®val, 1);
|
|
|
|
return (enum spirit_clkrecmode_e)(regval & 0x08);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_clkrecgain
|
|
*
|
|
* Description:
|
|
* Sets the clock recovery proportional gain.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* pgain - The Clock Recovery proportional gain to write in the
|
|
* CLK_REC_P_GAIN field of CLOCKREC register. This is the log2
|
|
* value of the clock recovery proportional gain. This value
|
|
* must be in the range [0:7].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_clkrecgain(FAR struct spirit_library_s *spirit,
|
|
uint8_t pgain)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_CLK_REC_P_GAIN(pgain));
|
|
|
|
/* Read the CLOCKREC register */
|
|
|
|
spirit_reg_read(spirit, CLOCKREC_BASE, ®val, 1);
|
|
|
|
/* Mask the CLK_REC_P_GAIN field and write the new value */
|
|
|
|
regval &= 0x1f;
|
|
regval |= (pgain << 5);
|
|
|
|
/* Set the CLOCKREC register */
|
|
|
|
return spirit_reg_write(spirit, CLOCKREC_BASE, ®val, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_clkrecgain
|
|
*
|
|
* Description:
|
|
* Returns the log2 of the clock recovery proportional gain.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Clock Recovery proportional gain read from the CLK_REC_P_GAIN field of
|
|
* CLOCKREC register. This value will be in the range [0:7].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_clkrecgain(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the CLOCKREC register, mask the CLK_REC_P_GAIN field and return the
|
|
* value */
|
|
|
|
(void)spirit_reg_read(spirit, CLOCKREC_BASE, ®val, 1);
|
|
|
|
return ((regval & 0xef) >> 5);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_clkrecigain
|
|
*
|
|
* Description:
|
|
* Sets the clock recovery integral gain.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* igain - The Clock Recovery integral gain to write in the CLK_REC_I_GAIN
|
|
* field of CLOCKREC register. This value must be in the range
|
|
* [0:15].
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_clkrecigain(FAR struct spirit_library_s *spirit,
|
|
uint8_t igain)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_CLK_REC_I_GAIN(igain));
|
|
|
|
/* Read the CLOCKREC register */
|
|
|
|
spirit_reg_read(spirit, CLOCKREC_BASE, ®val, 1);
|
|
|
|
/* Mask the CLK_REC_P_GAIN field and write the new value */
|
|
|
|
regval &= 0xf0;
|
|
regval |= igain;
|
|
|
|
/* Set the CLOCKREC register */
|
|
|
|
return spirit_reg_write(spirit, CLOCKREC_BASE, ®val, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_clkrecigain
|
|
*
|
|
* Description:
|
|
* Returns the clock recovery integral gain.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Clock Recovery integral gain read from the CLK_REC_I_GAIN field of
|
|
* CLOCKREC register. This value will be in the range [0:15].
|
|
*
|
|
******************************************************************************/
|
|
|
|
uint8_t spirit_radio_get_clkrecigain(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the CLOCKREC register, mask the CLK_REC_I_GAIN field and return the
|
|
* value.
|
|
*/
|
|
|
|
(void)spirit_reg_read(spirit, CLOCKREC_BASE, ®val, 1);
|
|
|
|
return (regval & 0x0f);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_clkrecpstfltlen
|
|
*
|
|
* Description:
|
|
* Sets the postfilter length for clock recovery algorithm.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* length - The postfilter length in symbols. This value can be one of
|
|
* the values defined in enum spirit_pstfltlen_e :
|
|
*
|
|
* PSTFLT_LENGTH_8 Postfilter length is 8 symbols
|
|
* PSTFLT_LENGTH_16 Postfilter length is 16 symbols
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success. A negated errno value is returned on any failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_clkrecpstfltlen(FAR struct spirit_library_s *spirit,
|
|
enum spirit_pstfltlen_e length)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Check the parameter */
|
|
|
|
DEBUGASSERT(IS_PST_FLT_LENGTH(length));
|
|
|
|
/* Read the CLOCKREC register */
|
|
|
|
spirit_reg_read(spirit, CLOCKREC_BASE, ®val, 1);
|
|
|
|
/* Mask the PSTFLT_LEN field and write the new value */
|
|
|
|
regval &= 0xef;
|
|
regval |= (uint8_t) length;
|
|
|
|
/* Set the CLOCKREC register */
|
|
|
|
return spirit_reg_write(spirit, CLOCKREC_BASE, ®val, 1);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_clkrecpstfltlen
|
|
*
|
|
* Description:
|
|
* Returns the postfilter length for clock recovery algorithm.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* Postfilter length in symbols. This value can be one of the values
|
|
* defined in enum spirit_pstfltlen_e:
|
|
*
|
|
* PSTFLT_LENGTH_8 Postfilter length is 8 symbols
|
|
* PSTFLT_LENGTH_16 Postfilter length is 16 symbols
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_pstfltlen_e
|
|
spirit_radio_get_clkrecpstfltlen(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
/* Read the CLOCKREC register, mask the PSTFLT_LEN field and return the
|
|
* value */
|
|
|
|
(void)spirit_reg_read(spirit, CLOCKREC_BASE, ®val, 1);
|
|
|
|
return (enum spirit_pstfltlen_e)(regval & 0x10);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_csblanking
|
|
*
|
|
* Description:
|
|
* Enables or Disables the received data blanking when the CS is under the
|
|
* threshold.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state of this mode.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_enable_csblanking(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 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)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= ANT_SELECT_CS_BLANKING_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~ANT_SELECT_CS_BLANKING_MASK);
|
|
}
|
|
|
|
/* Write the new value to the ANT_SELECT_CONF register */
|
|
|
|
ret = spirit_reg_write(spirit, ANT_SELECT_CONF_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_persistentrx
|
|
*
|
|
* Description:
|
|
* Enables or Disables the persistent RX mode.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state of this mode.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_persistentrx(FAR struct spirit_library_s *spirit,
|
|
enum spirit_functional_state_e newstate)
|
|
{
|
|
uint8_t regval = 0;
|
|
int ret;
|
|
|
|
/* Check the parameters */
|
|
|
|
DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate));
|
|
|
|
/* Read the PROTOCOL0_BASE and mask the PROTOCOL0_PERS_RX_MASK bitfield */
|
|
|
|
ret = spirit_reg_read(spirit, PROTOCOL0_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= PROTOCOL0_PERS_RX_MASK;
|
|
}
|
|
else
|
|
{
|
|
regval &= (~PROTOCOL0_PERS_RX_MASK);
|
|
}
|
|
|
|
/* Write the new value to the PROTOCOL0_BASE register */
|
|
|
|
ret = spirit_reg_write(spirit, PROTOCOL0_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_set_refdiv
|
|
*
|
|
* Description:
|
|
* Enables or Disables the synthesizer reference divider.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate new state for synthesizer reference divider.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_set_refdiv(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 SYNTH_CONFIG1_BASE and mask the REFDIV bit field */
|
|
|
|
ret = spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1);
|
|
if (ret >= 0)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval |= 0x80;
|
|
}
|
|
else
|
|
{
|
|
regval &= 0x7f;
|
|
}
|
|
|
|
/* Write the new value to the SYNTH_CONFIG1_BASE register */
|
|
|
|
ret = spirit_reg_write(spirit, SYNTH_CONFIG1_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_get_refdiv
|
|
*
|
|
* Description:
|
|
* Get the the synthesizer reference divider state.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* S_ENABLE or S_DISABLE. Errors are not reported.
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_functional_state_e
|
|
spirit_radio_get_refdiv(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
(void)spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1);
|
|
|
|
if (((regval >> 7) & 0x1) != 0)
|
|
{
|
|
return S_ENABLE;
|
|
}
|
|
else
|
|
{
|
|
return S_DISABLE;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_enable_digdivider
|
|
*
|
|
* Description:
|
|
* Enables or Disables the synthesizer reference divider.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
* newstate - New state for synthesizer reference divider.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
******************************************************************************/
|
|
|
|
int spirit_radio_enable_digdivider(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 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)
|
|
{
|
|
if (newstate == S_ENABLE)
|
|
{
|
|
regval &= 0xf7;
|
|
}
|
|
else
|
|
{
|
|
regval |= 0x08;
|
|
}
|
|
|
|
/* Write the new value to the XO_RCO_TEST_BASE register */
|
|
|
|
ret = spirit_reg_write(spirit, XO_RCO_TEST_BASE, ®val, 1);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Name: spirit_radio_isenabled_digdivider
|
|
*
|
|
* Description:
|
|
* Get the the synthesizer reference divider state.
|
|
*
|
|
* Input Parameters:
|
|
* spirit - Reference to a Spirit library state structure instance
|
|
*
|
|
* Returned Value:
|
|
* S_ENABLE or S_DISABLE. Error conditions are not detected.
|
|
*
|
|
******************************************************************************/
|
|
|
|
enum spirit_functional_state_e
|
|
spirit_radio_isenabled_digdivider(FAR struct spirit_library_s *spirit)
|
|
{
|
|
uint8_t regval;
|
|
|
|
(void)spirit_reg_read(spirit, XO_RCO_TEST_BASE, ®val, 1);
|
|
|
|
if (((regval >> 3) & 0x1) != 0)
|
|
{
|
|
return S_DISABLE;
|
|
}
|
|
else
|
|
{
|
|
return S_ENABLE;
|
|
}
|
|
}
|