diff --git a/drivers/wireless/spirit/drivers/spirit_netdev.c b/drivers/wireless/spirit/drivers/spirit_netdev.c index 8c9e19521e..fb0ce522c0 100644 --- a/drivers/wireless/spirit/drivers/spirit_netdev.c +++ b/drivers/wireless/spirit/drivers/spirit_netdev.c @@ -72,6 +72,7 @@ #include "spirit_pktbasic.h" #include "spirit_qi.h" #include "spirit_timer.h" +#include "spirit_csma.h" #include @@ -121,6 +122,7 @@ struct spirit_driver_s WDOG_ID txpoll; /* TX poll timer */ WDOG_ID txtimeout; /* TX timeout timer */ bool ifup; /* Spirit is on and interface is up */ + bool receiving; /* Radio is receiving a packet */ uint8_t panid[2]; /* PAN identifier, ffff = not set */ uint16_t saddr; /* Short address, ffff = not set */ uint8_t eaddr[8]; /* Extended address, ffffffffffffffff = not set */ @@ -229,17 +231,15 @@ static const struct spirit_gpio_init_s g_gpioinit = SPIRIT_GPIO_DIG_OUT_IRQ /* gpioio */ }; -#if 0 -static const struct spririt_csma_init_s g_csma_init = +static const struct spirit_csma_init_s g_csma_init = { + 1, /* BU counter seed */ S_ENABLE, /* enable persistent mode */ TBIT_TIME_64, /* Tcca time */ TCCA_TIME_3, /* Lcca length */ 3, /* max nr of backoffs (<8) */ - 1, /* BU counter seed */ 8 /* BU prescaler */ }; -#endif /**************************************************************************** * Private Functions @@ -325,20 +325,127 @@ static int spirit_txpoll(FAR struct net_driver_s *dev) static void spirit_interrupt_work(FAR void *arg) { - FAR struct spirit_driver_s *dev = (FAR struct spirit_driver_s *)arg; - uint8_t status = 0; + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)arg; + struct spirit_irqset_s irqstatus; - DEBUGASSERT(dev != NULL); + DEBUGASSERT(priv != NULL); + + /* Get the interrupt source from radio */ + + DEBUGVERIFY(spirit_irq_get_pending(spirit, &irqstatus)); + DEBUGVERIFY(spirit_irq_clr_pending(spirit)); /* Process the Spirit1 interrupt */ + /* First check for errors */ - wlinfo("Status: 0x%02X\n", status); - UNUSED(status); + if (irqstatus.IRQ_RX_FIFO_ERROR != 0) + { + wlwarn("WARNING: Rx FIFO Error\n"); + DEBUGVERIFY(spirit_command(spririt, CMD_FLUSHRXFIFO)); + priv->receiving = false; + } + + if (irqstatus.IRQ_TX_FIFO_ERROR != 0) + { + wlwarn("WARNING: Tx FIFO Error\n"); + DEBUGVERIFY(spirit_command(spririt, COMMAND_FLUSHTXFIFO)); + priv->receiving = false; + } + + /* The IRQ_TX_DATA_SENT bit notifies that a packet was sent. */ + + if (irqstatus.IRQ_TX_DATA_SENT != 0) + { + /* Put the Spirit back in the receiving state */ + + DEBUGVERIFY(spirit_management_rxstrobe(spirit)); + DEBUGVERIFY(spirit_command(spirit, CMD_RX)); + + /* Check if there are more packets to send */ +#warning Missing logic + } + + /* The IRQ_VALID_SYNC bit is used to notify a new packet is coming */ + + if (irqstatus.IRQ_VALID_SYNC != 0) + { + priv->receiving = true; + } + + /* The IRQ_RX_DATA_READY notifies that a new packet has been received */ + + if (irqstatus.IRQ_RX_DATA_READY != 0) + { + FAR struct iob_s *iob; + uint8_t count; + + /* Check the packet size */ + + count = spirit_fifo_get_rxcount(spirit); + if (count > CONFIG_IOB_BUFSIZE) + { + wlwarn("WARNING: Packet too large... dropping\n"); + } + else + { + /* Allocate an I/O buffer to hold the received packet. + * REVISIT: Not a good place to wait. Perhaps we should pre- + * allocate a few I/O buffers? + */ + + iob = iob_alloc(); + if (iob == NULL) + { + wlerr("ERROR: Packet too large... dropping\n"); + } + + /* Read the packet into the I/O buffer */ + + DEBUGVERIFY(spirit_fifo_read(count, iob->io_data); + iob->io_len = spirit_pktbasic_rxpktlen(spirit); + + DEBUGVERIFY(spirit_command(spririt, CMD_FLUSHRXFIFO)); + priv->receiving = false; + + /* Create the packet meta data and forward to the network */ +#warning Missing logic + } + } + + /* IRQ_RX_DATA_DISC indicates that Rx data wasdiscarded */ + + if (irqstatus.IRQ_RX_DATA_DISC) + { + DEBUGVERIFY(spirit_command(spririt, CMD_FLUSHRXFIFO)); + priv->receiving = false; + } + + /* Check the Spirit status. If it is IDLE, the setup to receive more */ + + DEBUGVERIFY(spirit_update_status(spirit)); + + if (spirit->u.state.MC_STATE == SPIRIT1_STATE_READY) + { + int timeout = 1000; + + /* Set up to receive */ + + DEBUGVERIFY(spirit_command(spririt, CMD_RX)); + + /* Wait for Spirit to enter the Tx state (or timeut) */ + + do + { + DEBUGVERIFY(spirit_update_status(spirit)); + timeout--; + } + while (spirit->u.state.MC_STATE != MC_STATE_RX && timeout > 0); + } /* Re-enable the interrupt. */ - DEBUGASSERT(dev->lower != NULL && dev->lower->enable != NULL); - dev->lower->enable(dev->lower, true); + DEBUGASSERT(priv->lower != NULL && priv->lower->enable != NULL); + priv->lower->enable(priv->lower, true); } /**************************************************************************** @@ -978,6 +1085,10 @@ int spirit_hw_initialize(FAR struct spirit_driver_s *priv, priv->ifup = false; + /* Perform VCO calibration WA when the radio is initialized */ + + spirit_radio_enable_wavco_calibration(spirit, S_ENABLE); + /* Configure the Spirit1 radio part */ ret = spirit_radio_initialize(spirit, &g_radio_init); @@ -1131,15 +1242,13 @@ int spirit_hw_initialize(FAR struct spirit_driver_s *priv, return ret; } -#if 0 /* Setup CSMA/CA */ - ret = csma_ca_init(&g_csma_init); + ret = spirit_csma_initialize(spirit, &g_csma_init); if (ret < 0) { return ret; } -#endif /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */ @@ -1218,27 +1327,27 @@ int spirit_netdev_initialize(FAR struct spi_dev_s *spi, /* Initialize the IEEE 802.15.4 network device fields */ - ieee = &priv->ieee; - ieee->i_get_mhrlen = spirit_get_mhrlen; /* Get MAC header length */ - ieee->i_req_data = spirit_req_data; /* Enqueue frame for transmission */ + ieee = &priv->ieee; + ieee->i_get_mhrlen = spirit_get_mhrlen; /* Get MAC header length */ + ieee->i_req_data = spirit_req_data; /* Enqueue frame for transmission */ /* Initialize the common network device fields */ - dev = &ieee->i_dev; + dev = &ieee->i_dev; #if 0 - dev->d_buf = pktbuf; /* Single packet buffer */ + dev->d_buf = pktbuf; /* Single packet buffer */ #endif - dev->d_ifup = spirit_ifup; /* I/F up (new IP address) callback */ - dev->d_ifdown = spirit_ifdown; /* I/F down callback */ - dev->d_txavail = spirit_txavail; /* New TX data callback */ + dev->d_ifup = spirit_ifup; /* I/F up (new IP address) callback */ + dev->d_ifdown = spirit_ifdown; /* I/F down callback */ + dev->d_txavail = spirit_txavail; /* New TX data callback */ #ifdef CONFIG_NET_IGMP - dev->d_addmac = spirit_addmac; /* Add multicast MAC address */ - dev->d_rmmac = spirit_rmmac; /* Remove multicast MAC address */ + dev->d_addmac = spirit_addmac; /* Add multicast MAC address */ + dev->d_rmmac = spirit_rmmac; /* Remove multicast MAC address */ #endif #ifdef CONFIG_NETDEV_IOCTL - dev->d_ioctl = spirit_ioctl; /* Handle network IOCTL commands */ + dev->d_ioctl = spirit_ioctl; /* Handle network IOCTL commands */ #endif - dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */ + dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */ /* Put the interface in the down state. This usually amounts to resetting * the device and/or calling spirit_ifdown(). diff --git a/drivers/wireless/spirit/include/spirit_calibration.h b/drivers/wireless/spirit/include/spirit_calibration.h new file mode 100644 index 0000000000..e5e6e77c09 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_calibration.h @@ -0,0 +1,227 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_calibration.h + * Configuration and management of SPIRIT VCO-RCO calibration. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * 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. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_CALIBRAITON_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_CALIBRAITON_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_config.h" +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in assertions */ + +#define IS_VCO_SEL(ref) ((ref) == VCO_L || (ref) == VCO_H) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +/* VCO_H / VCO_L selection. */ + +enum spirit_vcoselect_e +{ + VCO_L = 0, /* VCO lower */ + VCO_H /* VCO higher */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_calib_enable_rco + * + * Description: + * Enables or Disables the RCO calibration. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for RCO calibration. This parameter can be + * S_ENABLE or S_DISABLE. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_enable_rco(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_calib_enable_vco + * + * Description: + * Enables or Disables the VCO calibration. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for VCO calibration. This parameter can be + * S_ENABLE or S_DISABLE. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_enable_vco(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_calib_get_vcocal + * + * Description: + * Returns the VCO calibration data from internal VCO calibrator. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * VCO calibration data byte. + * + ******************************************************************************/ + +uint8_t spirit_calib_get_vcocal(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_calib_set_vcotxcal + * + * Description: + * Sets the VCO calibration data to be used in TX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * caldata - Calibration data word to be set. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_set_vcotxcal(FAR struct spirit_library_s *spirit, + uint8_t caldata); + +/****************************************************************************** + * Name: spirit_calib_get_vcotxcal + * + * Description: + * Returns the actual VCO calibration data used in TX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * VCO calibration data used in TX mode + * + ******************************************************************************/ + +uint8_t spirit_calib_get_vcotxcal(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_calib_set_vcorxcal + * + * Description: + * Sets the VCO calibration data to be used in RX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * caldata - Calibration data word to be set. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_set_vcorxcal(FAR struct spirit_library_s *spirit, + uint8_t caldata); + +/****************************************************************************** + * Name: spirit_calib_get_vcorxcal + * + * Description: + * Returns the actual VCO calibration data used in RX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Calibration data word used in RX mode. + * + ******************************************************************************/ + +uint8_t spirit_calib_get_vcorxcal(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_calib_select_vco + * + * Description: + * Selects a VCO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * vco - Can be VCO_H or VCO_L according to which VCO select. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_select_vco(FAR struct spirit_library_s *spirit, + enum spirit_vcoselect_e vco); + +/****************************************************************************** + * Name: spirit_calib_get_vco + * + * Description: + * Returns the VCO selected. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * VCO_H or VCO_L according to which VCO selected. + * + ******************************************************************************/ + +enum spirit_vcoselect_e spirit_calib_get_vco(FAR struct spirit_library_s *spirit); + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_CALIBRAITON_H */ diff --git a/drivers/wireless/spirit/include/spirit_csma.h b/drivers/wireless/spirit/include/spirit_csma.h new file mode 100644 index 0000000000..8a0a0732a3 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_csma.h @@ -0,0 +1,172 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_csma.h + * Configuration and management of SPIRIT CSMA. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * 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. + * + ******************************************************************************/ + +#ifndef __DRUVERS_WIRELESS_SPIRIT_INCLUDE_SPIRIT_CSMA_H +#define __DRUVERS_WIRELESS_SPIRIT_INCLUDE_SPIRIT_CSMA_H + +/* The Spirit CSMA feature, when configured and enabled, is transparent + * for the user. It means the user has only to call the spirit_csma_initialize() + * function on a filled structure and then enable the CSMA policy using the + * SpiritCsma() function. + * + * Example: + * + * struct spirit_csma_init_s g_csma_init = + * { + * 0xFA21, # BU counter seed + * S_DISABLE, # persistent mode + * TBIT_TIME_64, # Tbit time + * TCCA_TIME_3, # Tcca time + * 5, # max number of backoffs + * 32 # CU prescaler + * }; + * + * ... + * + * spirit_csma_initialize(spirit, &g_csma_init); + * spirit_csma(spirit, S_ENABLE); + * + * NOTE: The CS status depends of the RSSI threshold set. Please see + * spirit_qi.c for details. + */ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_types.h" +#include "spirit_regs.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Csma_Parameters */ + +#define IS_BU_COUNTER_SEED(seed) (seed!=0) +#define IS_BU_PRESCALER(prescaler) (prescaler < 64) +#define IS_CMAX_NB(nb) (nb < 8) + +/* Macros used in assertions */ + +#define IS_CCA_PERIOD(period) \ + ((period) == TBIT_TIME_64 || (period) == TBIT_TIME_128 || \ + (period) == TBIT_TIME_256 || (period) == TBIT_TIME_512) +#define IS_CSMA_LENGTH(len) \ + ((len) == TCCA_TIME_0 || (len) == TCCA_TIME_1 || \ + (len) == TCCA_TIME_2 || (len) == TCCA_TIME_3 || \ + (len) == TCCA_TIME_4 || (len) == TCCA_TIME_5 || \ + (len) == TCCA_TIME_6 || (len) == TCCA_TIME_7 || \ + (len) == TCCA_TIME_8 || (len) == TCCA_TIME_9 || \ + (len) == TCCA_TIME_10 || (len) == TCCA_TIME_11 || \ + (len) == TCCA_TIME_12 || (len) == TCCA_TIME_13 || \ + (len) == TCCA_TIME_14 || (len) == TCCA_TIME_15) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Multiplier for Tcca time enumeration (Tcca = Multiplier*Tbit). */ + +enum spirit_cca_period_e +{ + TBIT_TIME_64 = CSMA_CCA_PERIOD_64TBIT, /* CSMA/CA: Sets CCA period + * to 64*TBIT */ + TBIT_TIME_128 = CSMA_CCA_PERIOD_128TBIT, /* CSMA/CA: Sets CCA period + * to 128*TBIT */ + TBIT_TIME_256 = CSMA_CCA_PERIOD_256TBIT, /* CSMA/CA: Sets CCA period + * to 256*TBIT */ + TBIT_TIME_512 = CSMA_CCA_PERIOD_512TBIT, /* CSMA/CA: Sets CCA period + * to 512*TBIT */ +}; + +/* Multiplier of Tcca time enumeration to obtain Tlisten (Tlisten = [1...15]*Tcca). */ + +enum spirit_csmalen_e +{ + TCCA_TIME_0 = 0x00, /* CSMA/CA: Sets CCA length to 0 */ + TCCA_TIME_1 = 0x10, /* CSMA/CA: Sets CCA length to 1*TLISTEN */ + TCCA_TIME_2 = 0x20, /* CSMA/CA: Sets CCA length to 2*TLISTEN */ + TCCA_TIME_3 = 0x30, /* CSMA/CA: Sets CCA length to 3*TLISTEN */ + TCCA_TIME_4 = 0x40, /* CSMA/CA: Sets CCA length to 4*TLISTEN */ + TCCA_TIME_5 = 0x50, /* CSMA/CA: Sets CCA length to 5*TLISTEN */ + TCCA_TIME_6 = 0x60, /* CSMA/CA: Sets CCA length to 6*TLISTEN */ + TCCA_TIME_7 = 0x70, /* CSMA/CA: Sets CCA length to 7*TLISTEN */ + TCCA_TIME_8 = 0x80, /* CSMA/CA: Sets CCA length to 8*TLISTEN */ + TCCA_TIME_9 = 0x90, /* CSMA/CA: Sets CCA length to 9*TLISTEN */ + TCCA_TIME_10 = 0xa0, /* CSMA/CA: Sets CCA length to 10*TLISTEN */ + TCCA_TIME_11 = 0xb0, /* CSMA/CA: Sets CCA length to 11*TLISTEN */ + TCCA_TIME_12 = 0xc0, /* CSMA/CA: Sets CCA length to 12*TLISTEN */ + TCCA_TIME_13 = 0xd0, /* CSMA/CA: Sets CCA length to 13*TLISTEN */ + TCCA_TIME_14 = 0xe0, /* CSMA/CA: Sets CCA length to 14*TLISTEN */ + TCCA_TIME_15 = 0xf0, /* CSMA/CA: Sets CCA length to 15*TLISTEN */ +}; + +/* SPIRIT CSMA Init structure definition */ + +struct spirit_csma_init_s +{ + uint16_t seed; /* Specifies the BU counter seed. Not used + * in persistent mode. */ + uint8_t csmapersistent; /* Specifies if the CSMA persistent mode + * has to be on or off. This parameter can be + * S_ENABLE or S_DISABLE */ + uint8_t multbit; /* Specifies the Tbit multiplier to obtain the + * Tcca. This parameter can be a value from + * enum spirit_cca_period_e */ + uint8_t ccalen; /* Specifies the Tcca multiplier to determine + * the Tlisten. This parameter can be a value + * from enum spirit_csmalen_e. */ + uint8_t maxnb; /* Specifies the max number of backoff + * cycles. Not used in persistent mode. */ + uint8_t prescaler; /* Specifies the BU prescaler. Not used in + * persistent mode. */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* __DRUVERS_WIRELESS_SPIRIT_INCLUDE_SPIRIT_CSMA_H */ diff --git a/drivers/wireless/spirit/include/spirit_irq.h b/drivers/wireless/spirit/include/spirit_irq.h index 31d6934158..da5d436f4c 100644 --- a/drivers/wireless/spirit/include/spirit_irq.h +++ b/drivers/wireless/spirit/include/spirit_irq.h @@ -205,7 +205,7 @@ struct spirit_irqset_s uint8_t IRQ_RX_DATA_READY : 1; /* IRQ: RX data ready */ uint8_t IRQ_RX_DATA_DISC : 1; /* IRQ: RX data discarded - * (upon filtering) */ + * (upon filtering) */ uint8_t IRQ_TX_DATA_SENT : 1; /* IRQ: TX data sent */ uint8_t IRQ_MAX_RE_TX_REACH : 1; /* IRQ: Max re-TX reached */ uint8_t IRQ_CRC_ERROR : 1; /* IRQ: CRC error */ diff --git a/drivers/wireless/spirit/include/spirit_linearfifo.h b/drivers/wireless/spirit/include/spirit_linearfifo.h new file mode 100644 index 0000000000..8467acfa9a --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_linearfifo.h @@ -0,0 +1,260 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_Linearfifo.h + * Configuration and management of SPIRIT Fifo. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * 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. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_FIFO_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_FIFO_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_regs.h" +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in assertions */ + +#define IS_FIFO_THR(val) ((val) <= 96) + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/****************************************************************************** + * Name: spirit_fifo_get_rxcount + * + * Description: + * Returns the number of elements in the Rx FIFO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Number of elements in the Rx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_rxcount(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_fifo_get_txcount + * + * Description: + * Returns the number of elements in the Tx FIFO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Number of elements in the Tx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_txcount(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_fifo_set_rxalmostfull + * + * Description: + * Sets the almost full threshold for the Rx FIFO. When the number of + * elements in RX FIFO reaches this value an interrupt can be generated to + * the MCU. + * + * NOTE: The almost full threshold is encountered from the top of the FIFO. + * For example, if it is set to 7 the almost full FIFO irq will be raised + * when the number of elements is equals to 96-7 = 89. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * threshold almost full threshold. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_fifo_set_rxalmostfull(FAR struct spirit_library_s *spirit, + uint8_t threshold); + +/****************************************************************************** + * Name: spirit_fifo_get_rxalmostfull + * + * Description: + * Returns the almost full threshold for RX FIFO. + * + * NOTE: The almost full threshold is encountered from the top of the FIFO. + * For example, if it is 7 the almost full FIFO irq will be raised when the + * number of elements is equals to 96-7 = 89. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Almost full threshold for Rx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_rxalmostfull(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_fifo_set_rxalmostempty + * + * Description: + * Sets the almost empty threshold for the Rx FIFO. When the number of + * elements in RX FIFO reaches this value an interrupt can be generated to + * the MCU. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * threshold almost empty threshold. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_fifo_set_rxalmostempty(FAR struct spirit_library_s *spirit, + uint8_t threshold); + +/****************************************************************************** + * Name: spirit_fifo_get_rxalmostempty + * + * Description: + * Returns the almost empty threshold for Rx FIFO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Almost empty threshold for Rx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_rxalmostempty(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_fifo_set_txalmostfull + * + * Description: + * Sets the almost full threshold for the Tx FIFO. When the number of + * elements in TX FIFO reaches this value an interrupt can be generated to + * the MCU. + * + * NOTE: The almost full threshold is encountered from the top of the FIFO. + * For example, if it is set to 7 the almost full FIFO irq will be raised + * when the number of elements is equals to 96-7 = 89. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * threshold almost full threshold. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_fifo_set_txalmostfull(FAR struct spirit_library_s *spirit, + uint8_t threshold); + +/****************************************************************************** + * Name: spirit_fifo_get_txalmostfull + * + * Description: + * Returns the almost full threshold for Tx FIFO. + * + * NOTE: The almost full threshold is encountered from the top of the FIFO. + * For example, if it is set to 7 the almost full FIFO irq will be raised + * when the number of elements is equals to 96-7 = 89. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Almost full threshold for Tx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_txalmostfull(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_fifo_set_txalmostempty + * + * Description: + * Sets the almost empty threshold for the Tx FIFO. When the number of + * elements in Tx FIFO reaches this value an interrupt can can be generated + * to the MCU. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * threshold: almost empty threshold. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_fifo_set_txalmostempty(FAR struct spirit_library_s *spirit, + uint8_t threshold); + +/****************************************************************************** + * Name: spirit_fifo_get_txalmostempty + * + * Description: + * Returns the almost empty threshold for Tx FIFO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Almost empty threshold for Tx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_txalmostempty(FAR struct spirit_library_s *spirit); + +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_FIFO_H */ diff --git a/drivers/wireless/spirit/include/spirit_management.h b/drivers/wireless/spirit/include/spirit_management.h index 2bdf7f7c44..392731fb79 100644 --- a/drivers/wireless/spirit/include/spirit_management.h +++ b/drivers/wireless/spirit/include/spirit_management.h @@ -54,11 +54,59 @@ * Public Types ******************************************************************************/ - /****************************************************************************** * Public Function Prototypes ******************************************************************************/ +/****************************************************************************** + * Name: spirit_managment_wavco_calibration + * + * Description: + * Perform VCO calbration WA. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. + * + ******************************************************************************/ + +uint8_t spirit_managment_wavco_calibration(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_management_txstrobe + * + * Description: + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. + * + ******************************************************************************/ + +int spirit_management_txstrobe(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_management_rxstrobe + * + * Description: + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. + * + ******************************************************************************/ + +int spirit_management_rxstrobe(FAR struct spirit_library_s *spirit); + /****************************************************************************** * Name: spirit_management_initcommstate * diff --git a/drivers/wireless/spirit/include/spirit_pktbasic.h b/drivers/wireless/spirit/include/spirit_pktbasic.h index 831e8f9fa3..b661348057 100644 --- a/drivers/wireless/spirit/include/spirit_pktbasic.h +++ b/drivers/wireless/spirit/include/spirit_pktbasic.h @@ -99,6 +99,10 @@ * Pre-processor Definitions ******************************************************************************/ +/* PktBasic_Exported_Constants Pkt Basic Exported Constants */ + +#define IS_BASIC_LENGTH_WIDTH_BITS IS_PKT_LENGTH_WIDTH_BITS + /* Macros used in assertions */ /****************************************************************************** @@ -185,7 +189,7 @@ struct pktbasic_addr_s * * Input Parameters: * spirit - Reference to a Spirit library state structure instance - * pktpasic - Basic packet init structure. + * pktbasic - Basic packet init structure. * * Returned Value: * Zero (OK) on success; a negated errno value on failure. @@ -193,17 +197,61 @@ struct pktbasic_addr_s ******************************************************************************/ int spirit_pktbasic_initialize(FAR struct spirit_library_s *spirit, - FAR const struct pktbasic_init_s *pktpasic); + FAR const struct pktbasic_init_s *pktbasic); /****************************************************************************** - * Name: + * Name: spirit_pktbase_get_addrfield * * Description: + * Specifies if the Address field for SPIRIT Basic packets is enabled or + * disabled. * * Input Parameters: + * spirit - Reference to a Spirit library state structure instance * * Returned Value: + * Notifies if the address field is enabled or disabled. * ******************************************************************************/ +enum spirit_functional_state_e + spirit_pktbase_get_addrfield(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_pktbasic_set_payloadlen + * + * Description: + * Sets the payload length for SPIRIT Basic packets. Since the packet length + * depends from the address and the control field size, this function reads + * the correspondent registers in order to determine the correct packet + * length to be written. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * payloadlen - Payload length in bytes. + * + * Returned Value: + * Zero (OK) on success; a negated errno value is returned on any failure. + * + ******************************************************************************/ + +int spirit_pktbasic_set_payloadlen(FAR struct spirit_library_s *spirit, + uint16_t payloadlen); + +/****************************************************************************** + * Name: spirit_pktbasic_rxpktlen + * + * Description: + * Returns the packet length field of the received packet. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Rx Packet length. + * + ******************************************************************************/ + +uint16_t spirit_pktbasic_rxpktlen(FAR struct spirit_library_s *spirit); + #endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_PKTBASIC_H*/ diff --git a/drivers/wireless/spirit/include/spirit_pktcommon.h b/drivers/wireless/spirit/include/spirit_pktcommon.h index 48eac1ed18..219ba1cf52 100644 --- a/drivers/wireless/spirit/include/spirit_pktcommon.h +++ b/drivers/wireless/spirit/include/spirit_pktcommon.h @@ -63,8 +63,19 @@ * Pre-processor Definitions ******************************************************************************/ +/* Macro used to compute the lower part of the packet length, to write in + * the PCKTLEN0 and BUILD_PCKTLEN1 registers. len is the length of the + * packet payload. + */ + +#define BUILD_PCKTLEN0(len) ((len) & 0xff) +#define BUILD_PCKTLEN1(len) ((len) >> 8) + /* Macros used in assertions */ +#define IS_PKT_LENGTH_WIDTH_BITS(bits) ((bits) <= 16) +#define IS_PKT_SEQ_NUMBER_RELOAD(seqn) ((seqn) <= 3) + #define IS_PKT_PREAMBLE_LENGTH(len) \ ((len == PKT_PREAMBLE_LENGTH_01BYTE) || (len == PKT_PREAMBLE_LENGTH_02BYTES) || \ (len == PKT_PREAMBLE_LENGTH_03BYTES) || (len == PKT_PREAMBLE_LENGTH_04BYTES) || \ @@ -188,16 +199,58 @@ enum pkt_ctrllen_e ******************************************************************************/ /****************************************************************************** - * Name: + * Name: spirit_pktcommon_set_controllen * * Description: + * Sets the CONTROL field length for SPIRIT packets. * * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * ctrllen - Length of CONTROL field in bytes. * * Returned Value: + * Zero (OK) on success; a negated errno value on failure. * ******************************************************************************/ +int spirit_pktcommon_set_controllen(FAR struct spirit_library_s *spirit, + enum pkt_ctrllen_e ctrllen); + +/****************************************************************************** + * Name: spirit_pktcommon_get_controllen + * + * Description: + * Returns the CONTROL field length for SPIRIT packets. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Control field length. + * + ******************************************************************************/ + +uint8_t spirit_pktcommon_get_controllen(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_pktcommon_enable_crcfilter + * + * Description: + * Enables or Disables the filtering on CRC. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for CRC_CHECK. This parameter can be S_ENABLE or + * S_DISABLE. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_pktcommon_enable_crcfilter(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + #ifdef __cplusplus } #endif diff --git a/drivers/wireless/spirit/include/spirit_radio.h b/drivers/wireless/spirit/include/spirit_radio.h index 8b91b2fa90..d5e5dab36b 100644 --- a/drivers/wireless/spirit/include/spirit_radio.h +++ b/drivers/wireless/spirit/include/spirit_radio.h @@ -219,7 +219,7 @@ #define IS_CLK_REC_P_GAIN(gain) ((gain) <= 7) #define IS_CLK_REC_I_GAIN(gain) ((gain) <= 15) -/* Other acros used in assertions */ +/* Other macros used in assertions */ #define IS_XTAL_FLAG(flag) \ (((flag) == XTAL_FLAG_24_MHz) || ((flag) == XTAL_FLAG_26_MHz)) @@ -230,6 +230,9 @@ (((mod) == FSK) || ((mod) == GFSK_BT05) || \ ((mod) == GFSK_BT1) || ((mod) == ASK_OOK) || \ ((mod) == MSK)) +#define IS_PA_LOAD_CAP(cwc) \ + (((cwc) == LOAD_0_PF) || ((cwc) == LOAD_1_2_PF) || \ + ((cwc) == LOAD_2_4_PF) || ((cwc) == LOAD_3_6_PF)) /****************************************************************************** * Public Types @@ -265,6 +268,16 @@ enum modulation_select_e MSK = 0x30 /* MSK modulation selected */ }; +/* SPIRIT PA additional load capacitors bank enumeration */ + +enum spirit_paload_capacitor_e +{ + LOAD_0_PF = PA_POWER0_CWC_0, /* No additional PA load capacitor */ + LOAD_1_2_PF = PA_POWER0_CWC_1_2P, /* 1.2pF additional PA load capacitor */ + LOAD_2_4_PF = PA_POWER0_CWC_2_4P, /* 2.4pF additional PA load capacitor */ + LOAD_3_6_PF = PA_POWER0_CWC_3_6P /* 3.6pF additional PA load capacitor */ +}; + /* SPIRIT Radio initialization structure definition */ struct radio_init_s @@ -359,6 +372,30 @@ int spirit_radio_set_xtalflag(FAR struct spirit_library_s *spirit, enum xtal_flag_e spirit_radio_get_xtalflag(FAR struct spirit_library_s *spirit); +/****************************************************************************** + * 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); + /****************************************************************************** * Name: spirit_radio_get_synthword * @@ -437,6 +474,97 @@ int spirit_radio_set_band(FAR struct spirit_library_s *spirit, enum spirit_bandselect_e spirit_radio_get_band(FAR struct spirit_library_s *spirit); +/****************************************************************************** + * Name: spirit_radio_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); + +/****************************************************************************** + * 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); + +/****************************************************************************** + * 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); + +/****************************************************************************** + * Name: spirit_radio_get_channel + * + * Description: + * Returns the actual channel number. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Actual channel number. + * + ******************************************************************************/ + +uint8_t spirit_radio_get_channel(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_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); + /****************************************************************************** * Name: spirit_radio_set_basefrequency * @@ -459,7 +587,26 @@ int spirit_radio_set_basefrequency(FAR struct spirit_library_s *spirit, uint32_t fbase); /****************************************************************************** - * Name: + * 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); + +/****************************************************************************** + * Name: spirit_radio_get_basefrequency * * Description: * Returns the base carrier frequency. @@ -591,6 +738,50 @@ uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, int spirit_radio_set_palevel(FAR struct spirit_library_s *spirit, uint8_t ndx, float powerdbm); +/****************************************************************************** + * 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); + +/****************************************************************************** + * 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); + /****************************************************************************** * Name: spirit_radio_set_palevel_maxindex * diff --git a/drivers/wireless/spirit/include/spirit_spi.h b/drivers/wireless/spirit/include/spirit_spi.h index 7aa39f2b19..daa2b63a80 100644 --- a/drivers/wireless/spirit/include/spirit_spi.h +++ b/drivers/wireless/spirit/include/spirit_spi.h @@ -140,7 +140,7 @@ int spirit_reg_write(FAR struct spirit_library_s *spirit, uint8_t regaddr, int spirit_command(FAR struct spirit_library_s *spirit, uint8_t cmd); /****************************************************************************** - * Name: spirt_fifo_read + * Name: spirit_fifo_read * * Description: * Read data from RX FIFO @@ -156,11 +156,11 @@ int spirit_command(FAR struct spirit_library_s *spirit, uint8_t cmd); * ******************************************************************************/ -int spirt_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, - unsigned int buflen); +int spirit_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, + unsigned int buflen); /****************************************************************************** - * Name: spirt_fifo_write + * Name: spirit_fifo_write * * Description: * Write data into TX FIFO. @@ -176,8 +176,8 @@ int spirt_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, * ******************************************************************************/ -int spirt_fifo_write(FAR struct spirit_library_s *spirit, - FAR const uint8_t *buffer, unsigned int buflen); +int spirit_fifo_write(FAR struct spirit_library_s *spirit, + FAR const uint8_t *buffer, unsigned int buflen); /****************************************************************************** * Name: spirit_update_status diff --git a/drivers/wireless/spirit/include/spirit_types.h b/drivers/wireless/spirit/include/spirit_types.h index 7ea341e0c9..07aaf02724 100644 --- a/drivers/wireless/spirit/include/spirit_types.h +++ b/drivers/wireless/spirit/include/spirit_types.h @@ -135,9 +135,17 @@ struct spirit_status_s uint8_t reserved : 4; /* Reserved and equal to 5 */ }; -/* An instance of this structure represents the overall state of one Spirit +/* One instance of this structure represents the overall state of one Spirit * device from the standpoint of the library. Multiple spirit devices may be * supported by the library with multiple instances of this structure. + * + * The caller allocates memory for the instance of struct spirit_library_s + * and must provide these values: + * + * spi - The SPI instance to use to interface with the spirit chip + * xtal_frequency - The frequency of the crystal driving the spirit chip. + * + * All other fields should be set to zero. */ struct spirit_library_s @@ -153,6 +161,7 @@ struct spirit_library_s } u; uint8_t commstate; /* MANAGEMENT: Communication state */ + uint8_t vcocalib; /* RADIO: Enalbe VCO calibration WA */ }; #ifdef __cplusplus diff --git a/drivers/wireless/spirit/lib/Make.defs b/drivers/wireless/spirit/lib/Make.defs index 9cd2382355..3a00258898 100644 --- a/drivers/wireless/spirit/lib/Make.defs +++ b/drivers/wireless/spirit/lib/Make.defs @@ -35,8 +35,10 @@ # Include Spirit driver source files in the build -CSRCS += spirit_radio.c spirit_pktbasic.c spirit_qi.c spirit_management.c -CSRCS += spirit_irq.c spirit_timer.c spirit_gpio.c spirit_spi.c +CSRCS += spirit_radio.c spirit_pktbasic.c spirit_pktcommon.c spirit_qi.c +CSRCS += spirit_calibration.c spirit_management.c spirit_csma.c +CSRCS += spirit_linearfifo.c spirit_irq.c spirit_timer.c spirit_gpio.c +CSRCS += spirit_spi.c # Include Spirit driver build support diff --git a/drivers/wireless/spirit/lib/spirit_calibration.c b/drivers/wireless/spirit/lib/spirit_calibration.c new file mode 100644 index 0000000000..405b54b6d7 --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_calibration.c @@ -0,0 +1,384 @@ +/****************************************************************************** + * drivers/wireless/spirit/spirit_calibration.c + * Configuration and management of SPIRIT VCO-RCO calibration. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * 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 +#include + +#include "spirit_calibration.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_calib_enable_rco + * + * Description: + * Enables or Disables the RCO calibration. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for RCO calibration. This parameter can be + * S_ENABLE or S_DISABLE. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_enable_rco(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the register value */ + + ret = spirit_reg_read(spirit, PROTOCOL2_BASE, ®val, 1); + if (ret >= 0) + { + /* Build new value for the register */ + + if (newstate == S_ENABLE) + { + regval |= PROTOCOL2_RCO_CALIBRATION_MASK; + } + else + { + regval &= ~PROTOCOL2_RCO_CALIBRATION_MASK; + } + + /* Write register to enable or disable the RCO calibration */ + + ret = spirit_reg_write(spirit, PROTOCOL2_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_calib_enable_vco + * + * Description: + * Enables or Disables the VCO calibration. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for VCO calibration. This parameter can be + * S_ENABLE or S_DISABLE. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_enable_vco(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the register value */ + + ret = spirit_reg_read(spirit, PROTOCOL2_BASE, ®val, 1); + if (ret >= 0) + { + /* Build new value for the register */ + + if (newstate == S_ENABLE) + { + regval |= PROTOCOL2_VCO_CALIBRATION_MASK; + } + else + { + regval &= ~PROTOCOL2_VCO_CALIBRATION_MASK; + } + + /* Writes register to enable or disable the VCO calibration */ + + ret = spirit_reg_write(spirit, PROTOCOL2_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_calib_get_vcocal + * + * Description: + * Returns the VCO calibration data from internal VCO calibrator. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * VCO calibration data byte. + * + ******************************************************************************/ + +uint8_t spirit_calib_get_vcocal(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the register value */ + + (void)spirit_reg_read(spirit, RCO_VCO_CALIBR_OUT0_BASE, ®val, 1); + + /* Build and return the VCO calibration data value */ + + return (regval & 0x7f); +} + +/****************************************************************************** + * Name: spirit_calib_set_vcotxcal + * + * Description: + * Sets the VCO calibration data to be used in TX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * caldata - Calibration data word to be set. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_set_vcotxcal(FAR struct spirit_library_s *spirit, + uint8_t caldata) +{ + uint8_t regval; + int ret; + + /* Reads the register value */ + + ret = spirit_reg_read(spirit, RCO_VCO_CALIBR_IN1_BASE, ®val, 1); + if (ret >= 0) + { + /* Build the value to be written */ + + regval &= 0x80; + regval |= caldata; + + /* Writes the new value of calibration data in TX */ + + ret = spirit_reg_write(spirit, RCO_VCO_CALIBR_IN1_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_calib_get_vcotxcal + * + * Description: + * Returns the actual VCO calibration data used in TX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * VCO calibration data used in TX mode + * + ******************************************************************************/ + +uint8_t spirit_calib_get_vcotxcal(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the register containing the calibration data word used in TX mode */ + + (void)spirit_reg_read(spirit, RCO_VCO_CALIBR_IN1_BASE, ®val, 1); + + /* Mask the VCO_CALIBR_TX field and returns the value */ + + return (regval & 0x7f); +} + +/****************************************************************************** + * Name: spirit_calib_set_vcorxcal + * + * Description: + * Sets the VCO calibration data to be used in RX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * caldata - Calibration data word to be set. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_set_vcorxcal(FAR struct spirit_library_s *spirit, + uint8_t caldata) +{ + uint8_t regval; + int ret; + + /* Reads the register value */ + + ret = spirit_reg_read(spirit, RCO_VCO_CALIBR_IN0_BASE, ®val, 1); + if (ret >= 0) + { + /* Build the value to be written */ + + regval &= 0x80; + regval |= caldata; + + /* Write the new value of calibration data in RX */ + + ret = spirit_reg_write(spirit, RCO_VCO_CALIBR_IN0_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_calib_get_vcorxcal + * + * Description: + * Returns the actual VCO calibration data used in RX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Calibration data word used in RX mode. + * + ******************************************************************************/ + +uint8_t spirit_calib_get_vcorxcal(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the register containing the calibration data word used in TX mode */ + + (void)spirit_reg_read(spirit, RCO_VCO_CALIBR_IN0_BASE, ®val, 1); + + /* Mask the VCO_CALIBR_RX field and returns the value */ + + return (regval & 0x7f); +} + +/****************************************************************************** + * Name: spirit_calib_select_vco + * + * Description: + * Selects a VCO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * vco - Can be VCO_H or VCO_L according to which VCO select. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on any failure. + * + ******************************************************************************/ + +int spirit_calib_select_vco(FAR struct spirit_library_s *spirit, + enum spirit_vcoselect_e vco) +{ + uint8_t regval; + int ret; + + /* Check the parameter */ + + DEBUGASSERT(IS_VCO_SEL(vco)); + + ret = spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1); + if (ret >= 0) + { + regval &= 0xf9; + + if (vco == VCO_H) + { + regval |= 0x02; + } + else + { + regval |= 0x04; + } + + ret = spirit_reg_write(spirit, SYNTH_CONFIG1_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_calib_get_vco + * + * Description: + * Returns the VCO selected. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * VCO_H or VCO_L according to which VCO selected. + * + ******************************************************************************/ + +enum spirit_vcoselect_e spirit_calib_get_vco(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + (void)spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1); + + regval = (regval >> 1) & 0x3; + if (regval == 0x01) + { + return VCO_H; + } + else + { + return VCO_L; + } +} diff --git a/drivers/wireless/spirit/lib/spirit_csma.c b/drivers/wireless/spirit/lib/spirit_csma.c new file mode 100644 index 0000000000..e13801fe79 --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_csma.c @@ -0,0 +1,131 @@ +/****************************************************************************** + * drivers/wireless/spirit/spirit_csma.c + * Configuration and management of SPIRIT CSMA. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * 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 +#include + +#include "spirit_csma.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_csma_initialize + * + * Description: + * Initializes the SPIRIT CSMA according to the specified parameters in the + * struct spirit_csma_init_s. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * csmainit - Reference to the Csma init structure. + * + * Returned Value: + * Zero (OK) on success; A negated errno value is returned on any failure. + * + ******************************************************************************/ + +int spirit_csma_initialize(FAR struct spirit_library_s *spirit, + FAR struct spirit_csma_init_s *csmainit) +{ + uint8_t regval[5]; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(csmainit->csmapersistent)); + DEBUGASSERT(IS_CCA_PERIOD(csmainit->multbit)); + DEBUGASSERT(IS_CSMA_LENGTH(csmainit->ccalen)); + DEBUGASSERT(IS_BU_COUNTER_SEED(csmainit->seed)); + DEBUGASSERT(IS_BU_PRESCALER(csmainit->prescaler)); + DEBUGASSERT(IS_CMAX_NB(csmainit->maxnb)); + + /* CSMA BU counter seed (MSB) config */ + + regval[0] = (uint8_t)(csmainit->seed >> 8); + + /* CSMA BU counter seed (LSB) config */ + + regval[1] = (uint8_t)csmainit->seed; + + /* CSMA BU prescaler config and CCA period config */ + + regval[2] = (csmainit->prescaler << 2) | csmainit->multbit; + + /* CSMA CCA length config and max number of back-off */ + + regval[3] = (csmainit->ccalen | csmainit->maxnb); + + /* Reads the PROTOCOL1_BASE register value, to write the SEED_RELOAD and + * CSMA_PERS_ON fields/ + */ + + ret = spirit_reg_read(spirit, PROTOCOL1_BASE, ®val[4], 1); + if (ret < 0) + { + return ret; + } + + /* Writes the new value for persistent mode */ + + if (csmainit->csmapersistent == S_ENABLE) + { + regval[4] |= PROTOCOL1_CSMA_PERS_ON_MASK; + } + else + { + regval[4] &= ~PROTOCOL1_CSMA_PERS_ON_MASK; + } + + /* Writes PROTOCOL1_BASE register */ + + ret = spirit_reg_write(spirit, PROTOCOL1_BASE, ®val[4], 1); + if (ret < 0) + { + return ret; + } + + /* Writes CSMA_CONFIGx_BASE registers */ + + ret = spirit_reg_write(spirit, CSMA_CONFIG3_BASE, regval, 4); + return ret; +} diff --git a/drivers/wireless/spirit/lib/spirit_linearfifo.c b/drivers/wireless/spirit/lib/spirit_linearfifo.c new file mode 100644 index 0000000000..51bfcd3156 --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_linearfifo.c @@ -0,0 +1,386 @@ +/****************************************************************************** + * drivers/wireless/spirit/spirit_Linearfifo.c + * Configuration and management of SPIRIT Fifo. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * 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 + +#include "spirit_Linearfifo.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_fifo_get_rxcount + * + * Description: + * Returns the number of elements in the Rx FIFO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Number of elements in the Rx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_rxcount(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the register value */ + + (void)spirit_reg_read(spirit, LINEAR_FIFO_STATUS0_BASE, ®val, 1); + + /* Build and return value */ + + return (regval & 0x7f); +} + +/****************************************************************************** + * Name: spirit_fifo_get_txcount + * + * Description: + * Returns the number of elements in the Tx FIFO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Number of elements in the Tx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_txcount(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the number of elements in TX FIFO and return the value */ + + (void)spirit_reg_read(spirit, LINEAR_FIFO_STATUS1_BASE, ®val, 1); + + /* Build and return value */ + + return (regval & 0x7F); +} + +/****************************************************************************** + * Name: + * + * Description: + * Sets the almost full threshold for the Rx FIFO. When the number of + * elements in RX FIFO reaches this value an interrupt can be generated to + * the MCU. + * + * NOTE: The almost full threshold is encountered from the top of the FIFO. + * For example, if it is set to 7 the almost full FIFO irq will be raised + * when the number of elements is equals to 96-7 = 89. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * threshold almost full threshold. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_fifo_set_rxalmostfull(FAR struct spirit_library_s *spirit, + uint8_t threshold) +{ + uint8_t regval; + + /* Check the parameters */ + + DEBUGASSERT(IS_FIFO_THR(threshold)); + + /* Build the register value */ + + regval = threshold & 0x7f; + + /* Writes the Almost Full threshold for RX in the corresponding register */ + + return spirit_reg_write(spirit, FIFO_CONFIG3_RXAFTHR_BASE, ®val, 1); +} + +/****************************************************************************** + * Name: spirit_fifo_get_rxalmostfull + * + * Description: + * Returns the almost full threshold for RX FIFO. + * + * NOTE: The almost full threshold is encountered from the top of the FIFO. + * For example, if it is 7 the almost full FIFO irq will be raised when the + * number of elements is equals to 96-7 = 89. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Almost full threshold for Rx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_rxalmostfull(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the almost full threshold for RX FIFO and return the value */ + + (void)spirit_reg_read(spirit, FIFO_CONFIG3_RXAFTHR_BASE, ®val, 1); + + /* Build and return value */ + + return (regval & 0x7f); +} + +/****************************************************************************** + * Name: spirit_fifo_set_rxalmostempty + * + * Description: + * Sets the almost empty threshold for the Rx FIFO. When the number of + * elements in RX FIFO reaches this value an interrupt can be generated to + * the MCU. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * threshold almost empty threshold. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_fifo_set_rxalmostempty(FAR struct spirit_library_s *spirit, + uint8_t threshold) +{ + uint8_t regval; + + /* Check the parameters */ + + DEBUGASSERT(IS_FIFO_THR(threshold)); + + /* Build the register value */ + + regval = threshold & 0x7f; + + /* Writes the Almost Empty threshold for RX in the corresponding register */ + + return spirit_reg_write(spirit, FIFO_CONFIG2_RXAETHR_BASE, ®val, 1); +} + +/****************************************************************************** + * Name: spirit_fifo_get_rxalmostempty + * + * Description: + * Returns the almost empty threshold for Rx FIFO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Almost empty threshold for Rx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_rxalmostempty(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the almost empty threshold for RX FIFO and returns the value */ + + (void)spirit_reg_read(spirit, FIFO_CONFIG2_RXAETHR_BASE, ®val, 1); + + /* Build and return value */ + + return (regval & 0x7f); +} + +/****************************************************************************** + * Name: spirit_fifo_set_txalmostfull + * + * Description: + * Sets the almost full threshold for the Tx FIFO. When the number of + * elements in TX FIFO reaches this value an interrupt can be generated to + * the MCU. + * + * NOTE: The almost full threshold is encountered from the top of the FIFO. + * For example, if it is set to 7 the almost full FIFO irq will be raised + * when the number of elements is equals to 96-7 = 89. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * threshold almost full threshold. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_fifo_set_txalmostfull(FAR struct spirit_library_s *spirit, + uint8_t threshold) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_FIFO_THR(threshold)); + + /* Reads the register value */ + + ret = spirit_reg_read(spirit, FIFO_CONFIG1_TXAFTHR_BASE, ®val, 1); + if (ret >= 0) + { + /* Build the register value */ + + regval &= 0x80; + regval |= threshold; + + /* Writes the Almost Full threshold for Tx in the corresponding register */ + + ret = spirit_reg_write(spirit, FIFO_CONFIG1_TXAFTHR_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_fifo_get_txalmostfull + * + * Description: + * Returns the almost full threshold for Tx FIFO. + * + * NOTE: The almost full threshold is encountered from the top of the FIFO. + * For example, if it is set to 7 the almost full FIFO irq will be raised + * when the number of elements is equals to 96-7 = 89. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Almost full threshold for Tx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_txalmostfull(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the almost full threshold for Tx FIFO and returns the value */ + + (void)spirit_reg_read(spirit, FIFO_CONFIG1_TXAFTHR_BASE, ®val, 1); + + /* Build and returns value */ + + return (regval & 0x7F); +} + +/****************************************************************************** + * Name: spirit_fifo_set_txalmostempty + * + * Description: + * Sets the almost empty threshold for the Tx FIFO. When the number of + * elements in Tx FIFO reaches this value an interrupt can can be generated + * to the MCU. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * threshold: almost empty threshold. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_fifo_set_txalmostempty(FAR struct spirit_library_s *spirit, + uint8_t threshold) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_FIFO_THR(threshold)); + + /* Reads the register value */ + + ret = spirit_reg_read(spirit, FIFO_CONFIG0_TXAETHR_BASE, ®val, 1); + if (ret >= 0) + { + /* Build the register value */ + + regval &= 0x80; + regval |= threshold; + + /* Writes the Almost Empty threshold for Tx in the corresponding register */ + + ret = spirit_reg_write(spirit, FIFO_CONFIG0_TXAETHR_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_fifo_get_txalmostempty + * + * Description: + * Returns the almost empty threshold for Tx FIFO. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Almost empty threshold for Tx FIFO. + * + ******************************************************************************/ + +uint8_t spirit_fifo_get_txalmostempty(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the almost empty threshold for TX FIFO and returns the value */ + + (void)spirit_reg_read(spirit, FIFO_CONFIG0_TXAETHR_BASE, ®val, 1); + + /* Build and return value */ + + return (regval & 0x7f); +} diff --git a/drivers/wireless/spirit/lib/spirit_management.c b/drivers/wireless/spirit/lib/spirit_management.c index a4b130921d..508095c184 100644 --- a/drivers/wireless/spirit/lib/spirit_management.c +++ b/drivers/wireless/spirit/lib/spirit_management.c @@ -2,12 +2,12 @@ * drivers/wireless/spirit/lib/spirit_management.c * The management layer for SPIRIT1 library. * - * Copyright(c) 2015 STMicroelectronics - * Author: VMA division - AMS - * Version 3.2.2 08-July-2015 + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 * - * Adapted for NuttX by: - * Author: Gregory Nutt + * Adapted for NuttX by: + * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -38,6 +38,14 @@ * Included Files ******************************************************************************/ +#include +#include +#include + +#include "spirit_commands.h" +#include "spirit_spi.h" +#include "spirit_radio.h" +#include "spirit_calibration.h" #include "spirit_management.h" /****************************************************************************** @@ -48,25 +56,500 @@ #define COMMUNICATION_STATE_RX 1 #define COMMUNICATION_STATE_NONE 2 +/****************************************************************************** + * 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_bandreg[4] = +{ + SYNT0_BS_6, SYNT0_BS_12, SYNT0_BS_16, SYNT0_BS_32 +}; + +/* BS value to write in the SYNT0 register according to the selected band */ + /****************************************************************************** * Private Functions ******************************************************************************/ /****************************************************************************** - * Name: + * Name: spirit_management_set_basefrequency * * Description: + * spirit_management_set_basefrequency function only used in + * spirit_managment_wavco_calibration. * - * Parameters: + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fbase - the base carrier frequency expressed in Hz as unsigned word. * * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. * ******************************************************************************/ +static int + spirit_management_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 band = 0; + uint8_t anaregs[4]; + uint8_t wcp; + uint8_t chnum; + uint8_t refdiv; + + /* 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 if (IS_FREQUENCY_BAND_VERY_LOW(fbase)) + { + 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; + + /* Reads the reference divider */ + + refdiv = (uint8_t)spirit_radio_get_refdiv(spirit) + 1; + + 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 * ((double)(FBASE_DIVIDER * refdiv * g_vectc_bhalf[band]) / + 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_bandreg[band]); + + /* Configures the needed Analog Radio registers */ + + return spirit_reg_write(spirit, SYNT3_BASE, anaregs, 4); +} + /****************************************************************************** * Public Functions ******************************************************************************/ +/****************************************************************************** + * Name: spirit_managment_wavco_calibration + * + * Description: + * Perform VCO calbration WA. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. + * + ******************************************************************************/ + +uint8_t spirit_managment_wavco_calibration(FAR struct spirit_library_s *spirit) +{ + uint32_t basefreq; + uint8_t vco_rxword; + uint8_t vco_txword; + uint8_t tmp; + bool restore = false; + bool standby = false; + int ret; + + /* Enable the reference divider if the XTAL is between 48 and 52 MHz */ + + if (spirit->xtal_frequency > DOUBLE_XTAL_THR) + { + if (spirit_radio_get_refdiv(spirit) == S_DISABLE) + { + restore = true; + basefreq = spirit_radio_get_basefrequency(spirit); + ret = spirit_radio_set_refdiv(spirit, S_ENABLE); + + ret = spirit_management_set_basefrequency(spirit, basefreq); + if (ret < 0) + { + return ret; + } + } + } + + basefreq = spirit_radio_get_basefrequency(spirit); + + /* Increase the VCO current */ + + tmp = 0x19; + ret = spirit_reg_write(spirit, 0xa1, &tmp, 1); + if (ret < 0) + { + return ret; + } + + ret = spirit_calib_enable_vco(spirit, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_update_status(spirit); + if (ret < 0) + { + return ret; + } + + if (spirit->u.state.MC_STATE == MC_STATE_STANDBY) + { + standby = true; + ret = spirit_command(spirit, CMD_READY); + if (ret < 0) + { + return ret; + } + + do + { + ret = spirit_update_status(spirit); + if (ret < 0) + { + return ret; + } + + if (spirit->u.state.MC_STATE == 0x13) + { + return -EIO; + } + } + while (spirit->u.state.MC_STATE != MC_STATE_READY); + } + + ret = spirit_command(spirit, CMD_LOCKTX); + if (ret < 0) + { + return ret; + } + + do + { + ret = spirit_update_status(spirit); + if (ret < 0) + { + return ret; + } + + if (spirit->u.state.MC_STATE == 0x13) + { + return -EIO; + } + } + while (spirit->u.state.MC_STATE != MC_STATE_LOCK); + + vco_txword = spirit_calib_get_vcocal(spirit); + + ret = spirit_command(spirit, CMD_READY); + if (ret < 0) + { + return ret; + } + + do + { + ret = spirit_update_status(spirit); + if (ret < 0) + { + return ret; + } + } + while (spirit->u.state.MC_STATE != MC_STATE_READY); + + ret = spirit_command(spirit, CMD_LOCKRX); + if (ret < 0) + { + return ret; + } + + do + { + ret = spirit_update_status(spirit); + if (ret < 0) + { + return ret; + } + + if (spirit->u.state.MC_STATE == 0x13) + { + return -EIO; + } + } + while (spirit->u.state.MC_STATE != MC_STATE_LOCK); + + vco_rxword = spirit_calib_get_vcocal(spirit); + + ret = spirit_command(spirit, CMD_READY); + if (ret < 0) + { + return ret; + } + + do + { + ret = spirit_update_status(spirit); + if (ret < 0) + { + return ret; + } + + if (spirit->u.state.MC_STATE == 0x13) + { + return 1; + } + } + while (spirit->u.state.MC_STATE != MC_STATE_READY); + + if (standby) + { + ret = spirit_command(spirit, CMD_STANDBY); + if (ret < 0) + { + return ret; + } + } + + ret = spirit_calib_enable_vco(spirit, S_DISABLE); + if (ret < 0) + { + return ret; + } + + /* Disable the reference divider if the XTAL is between 48 and 52 MHz */ + + if (restore) + { + ret = spirit_radio_set_refdiv(spirit, S_DISABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_management_set_basefrequency(spirit, basefreq); + if (ret < 0) + { + return ret; + } + } + + /* Restore the VCO current */ + + tmp = 0x11; + ret = spirit_reg_write(spirit, 0xa1, &tmp, 1); + if (ret < 0) + { + return ret; + } + + spirit_calib_set_vcotxcal(spirit, vco_txword); + spirit_calib_set_vcorxcal(spirit, vco_rxword); + + return OK; +} + +/****************************************************************************** + * Name: spirit_management_txstrobe + * + * Description: + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. + * + ******************************************************************************/ + +int spirit_management_txstrobe(FAR struct spirit_library_s *spirit) +{ + if (spirit->commstate != COMMUNICATION_STATE_TX) + { + uint8_t tmp; + int ret; + + /* To achive the max output power */ + + if (spirit->commfrequency >= 150000000 && + spirit->commfrequency <= 470000000) + { + /* Optimal setting for Tx mode only */ + + ret = spirit_radio_set_outputload(spirit, LOAD_3_6_PF); + } + else + { + /* Optimal setting for Tx mode only */ + + ret = spirit_radio_set_outputload(spirit, LOAD_0_PF); + } + + if (ret < 0) + { + return ret; + } + + /* Enable VCO_L buffer */ + + tmp = 0x11; + ret = spirit_reg_write(spirit, 0xa9, &tmp, 1); + if (ret < 0) + { + return ret; + } + + /* Set SMPS switching frequency */ + + tmp = 0x20; + ret = spirit_reg_write(spirit, PM_CONFIG1_BASE, &tmp, 1); + if (ret < 0) + { + return ret; + } + + spirit->commstate = COMMUNICATION_STATE_TX; + } + + return OK; +} + +/****************************************************************************** + * Name: spirit_management_rxstrobe + * + * Description: + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned on + * any failure. + * + ******************************************************************************/ + +int spirit_management_rxstrobe(FAR struct spirit_library_s *spirit) +{ + uint8_t tmp; + int ret; + + if (spirit->commstate != COMMUNICATION_STATE_RX) + { + /* Set SMPS switching frequency */ + + tmp = 0x98; + ret = spirit_reg_write(spirit, PM_CONFIG1_BASE, &tmp, 1); + if (ret < 0) + { + return ret; + } + + /* Set the correct CWC parameter */ + + ret = spirit_radio_set_outputload(spirit, LOAD_0_PF); + if (ret < 0) + { + return ret; + } + + spirit->commstate = COMMUNICATION_STATE_RX; + } + + return OK; +} + /****************************************************************************** * Name: spirit_management_initcommstate * @@ -78,6 +561,7 @@ * frequency - Desired communication frequency * * Returned Value: + * None * ******************************************************************************/ diff --git a/drivers/wireless/spirit/lib/spirit_pktbasic.c b/drivers/wireless/spirit/lib/spirit_pktbasic.c index e6a58c3a8f..437e51dce5 100644 --- a/drivers/wireless/spirit/lib/spirit_pktbasic.c +++ b/drivers/wireless/spirit/lib/spirit_pktbasic.c @@ -38,30 +38,12 @@ * Included Files ******************************************************************************/ +#include #include #include "spirit_pktbasic.h" #include "spirit_spi.h" -/****************************************************************************** - * Pre-processor Definitions - ******************************************************************************/ - -/****************************************************************************** - * Private Functions - ******************************************************************************/ - -/****************************************************************************** - * Name: - * - * Description: - * - * Parameters: - * - * Returned Value: - * - ******************************************************************************/ - /****************************************************************************** * Public Functions ******************************************************************************/ @@ -87,6 +69,263 @@ int spirit_pktbasic_initialize(FAR struct spirit_library_s *spirit, FAR const struct pktbasic_init_s *pktpasic) { -#warning Missing logic - return -ENOSYS; -} \ No newline at end of file + uint8_t regval[4]; + uint8_t pktlenwidth; + uint8_t i; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_PKT_PREAMBLE_LENGTH(pktpasic->premblen)); + DEBUGASSERT(IS_PKT_SYNC_LENGTH(pktpasic->synclen)); + DEBUGASSERT(IS_PKT_CRC_MODE(pktpasic->crcmode)); + DEBUGASSERT(IS_PKT_LENGTH_WIDTH_BITS(pktpasic->pktlenwidth)); + DEBUGASSERT(IS_PKT_FIX_VAR_LENGTH(pktpasic->fixedvarlen)); + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(pktpasic->txdestaddr)); + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(pktpasic->fec)); + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(pktpasic->datawhite)); + DEBUGASSERT(IS_PKT_CONTROL_LENGTH(pktpasic->ctrllen)); + + /* Reads the PROTOCOL1 register */ + + ret = spirit_reg_read(spirit, PROTOCOL1_BASE, ®val[0], 1); + + /* Mask a reserved bit */ + + regval[0] &= ~0x20; + + /* Always set the automatic packet filtering */ + + regval[0] |= PROTOCOL1_AUTO_PCKT_FLT_MASK; + + /* Writes the value on register */ + + ret = spirit_reg_write(spirit, PROTOCOL1_BASE, ®val[0], 1); + if (ret < 0) + { + return ret; + } + + /* Reads the PCKT_FLT_OPTIONS register */ + + ret = spirit_reg_read(spirit, PCKT_FLT_OPTIONS_BASE, ®val[0], 1); + if (ret < 0) + { + return ret; + } + + /* Always reset the control and source filtering (also if it is not present + * in basic) */ + + regval[0] &= ~(PCKT_FLT_OPTIONS_SOURCE_FILTERING_MASK | + PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK); + + /* Writes the value on register */ + + ret = spirit_reg_write(spirit, PCKT_FLT_OPTIONS_BASE, ®val[0], 1); + if (ret < 0) + { + return ret; + } + + if (pktpasic->txdestaddr == S_ENABLE) + { + regval[0] = 0x08; + } + else + { + regval[0] = 0x00; + } + + /* Address and control length setting */ + + regval[0] |= (uint8_t)pktpasic->ctrllen; + + /* Packet format and width length setting */ + + pktlenwidth = pktpasic->pktlenwidth; + if (pktlenwidth == 0) + { + pktlenwidth = 1; + } + + regval[1] = (uint8_t)PCKTCTRL3_PCKT_FRMT_BASIC | (uint8_t)(pktlenwidth - 1); + + /* Preamble, sync and fixed or variable length setting */ + + regval[2] = (uint8_t)pktpasic->premblen | (uint8_t)pktpasic->synclen | + (uint8_t)pktpasic->fixedvarlen; + + /* CRC length, whitening and FEC setting */ + + regval[3] = (uint8_t)pktpasic->crcmode; + + if (pktpasic->datawhite == S_ENABLE) + { + regval[3] |= PCKTCTRL1_WHIT_MASK; + } + + if (pktpasic->fec == S_ENABLE) + { + regval[3] |= PCKTCTRL1_FEC_MASK; + } + + /* Writes registers */ + + ret = spirit_reg_write(spirit, PCKTCTRL4_BASE, regval, 4); + if (ret < 0) + { + return ret; + } + + /* Sync words setting */ + + for (i = 0; i < 4; i++) + { + if (i < 3 - (pktpasic->synclen >> 1)) + { + regval[i] = 0; + } + else + { + regval[i] = (uint8_t)(pktpasic->syncwords >> (8 * i)); + } + } + + /* Sets CRC check bit */ + + if (pktpasic->crcmode == PKT_NO_CRC) + { + ret = spirit_pktcommon_enable_crcfilter(spirit, S_DISABLE); + } + else + { + ret = spirit_pktcommon_enable_crcfilter(spirit, S_ENABLE); + } + + if (ret < 0) + { + return ret; + } + + return spirit_reg_write(spirit, SYNC4_BASE, regval, 4); +} + +/****************************************************************************** + * Name: spirit_pktbase_get_addrfield + * + * Description: + * Specifies if the Address field for SPIRIT Basic packets is enabled or + * disabled. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Notifies if the address field is enabled or disabled. + * + ******************************************************************************/ + +enum spirit_functional_state_e + spirit_pktbase_get_addrfield(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the PCKTCTRL4 register value */ + + (void)spirit_reg_read(spirit, PCKTCTRL4_BASE, ®val, 1); + + /* Returns the address field value */ + + if ((regval & PCKTCTRL4_ADDRESS_LEN_MASK) != 0) + { + return S_ENABLE; + } + else + { + return S_DISABLE; + } +} + +/****************************************************************************** + * Name: spirit_pktbasic_set_payloadlen + * + * Description: + * Sets the payload length for SPIRIT Basic packets. Since the packet length + * depends from the address and the control field size, this function reads + * the correspondent registers in order to determine the correct packet + * length to be written. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * payloadlen - Payload length in bytes. + * + * Returned Value: + * Zero (OK) on success; a negated errno value is returned on any failure. + * + ******************************************************************************/ + +int spirit_pktbasic_set_payloadlen(FAR struct spirit_library_s *spirit, + uint16_t payloadlen) +{ + uint8_t regval[2]; + uint16_t oversize = 0; + + /* Computes the oversize (address + control) size */ + + if (spirit_pktbase_get_addrfield(spirit)) + { + oversize = 1; + } + + oversize += (uint16_t)spirit_pktcommon_get_controllen(spirit); + + /* Computes PCKTLEN0 value from payloadlen */ + + regval[1] = BUILD_PCKTLEN0(payloadlen + oversize); + + /* Computes PCKTLEN1 value from payloadlen */ + + regval[0] = BUILD_PCKTLEN1(payloadlen + oversize); + + /* Writes data on the PCKTLEN1/0 register */ + + return spirit_reg_write(spirit, PCKTLEN1_BASE, regval, 2); +} + +/****************************************************************************** + * Name: spirit_pktbasic_rxpktlen + * + * Description: + * Returns the packet length field of the received packet. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Rx Packet length. + * + ******************************************************************************/ + +uint16_t spirit_pktbasic_rxpktlen(FAR struct spirit_library_s *spirit) +{ + uint8_t regval[2]; + uint16_t oversize = 0; + + /* Computes the oversize (address + control) size */ + + if (spirit_pktbase_get_addrfield(spirit)) + { + oversize = 1; + } + + oversize += (uint16_t)spirit_pktcommon_get_controllen(spirit); + + /* Reads the RX_PCKT_LENx registers value */ + + (void)spirit_reg_read(spirit, RX_PCKT_LEN1_BASE, regval, 2); + + /* Rebuild and return the length field */ + + return (((((uint16_t) regval[0]) << 8) + (uint16_t)regval[1]) - oversize); +} diff --git a/drivers/wireless/spirit/lib/spirit_pktcommon.c b/drivers/wireless/spirit/lib/spirit_pktcommon.c new file mode 100644 index 0000000000..510fbaa16e --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_pktcommon.c @@ -0,0 +1,168 @@ +/****************************************************************************** + * drivers/wireless/spirit/spirit_pktcommon.c + * Configuration and management of the common features of SPIRIT packets. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * 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 + +#include "spirit_pktcommon.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_pktcommon_set_controllen + * + * Description: + * Sets the CONTROL field length for SPIRIT packets. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * ctrllen - Length of CONTROL field in bytes. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_pktcommon_set_controllen(FAR struct spirit_library_s *spirit, + enum pkt_ctrllen_e ctrllen) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_PKT_CONTROL_LENGTH(ctrllen)); + + /* Reads the PCKTCTRL4 register value */ + + ret = spirit_reg_read(spirit, PCKTCTRL4_BASE, ®val, 1); + if (ret >= 0) + { + /* Set the control length */ + + regval &= ~PCKTCTRL4_CONTROL_LEN_MASK; + regval |= (uint8_t)ctrllen; + + /* Write the new value on the PCKTCTRL4 register */ + + ret = spirit_reg_write(spirit, PCKTCTRL4_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_pktcommon_get_controllen + * + * Description: + * Returns the CONTROL field length for SPIRIT packets. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Control field length. + * + ******************************************************************************/ + +uint8_t spirit_pktcommon_get_controllen(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the PCKTCTRL4 register value */ + + (void)spirit_reg_read(spirit, PCKTCTRL4_BASE, ®val, 1); + + /* Rebuild and return value */ + + return (regval & PCKTCTRL4_CONTROL_LEN_MASK); +} + +/****************************************************************************** + * Name: spirit_pktcommon_enable_crcfilter + * + * Description: + * Enables or Disables the filtering on CRC. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for CRC_CHECK. This parameter can be S_ENABLE or + * S_DISABLE. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_pktcommon_enable_crcfilter(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the PCKT_FLT_OPTIONS register value */ + + ret = spirit_reg_read(spirit, PCKT_FLT_OPTIONS_BASE, ®val, 1); + if (ret >= 0) + { + /* Modify the register value: enable or disable the CRC filtering */ + + if (newstate == S_ENABLE) + { + regval |= PCKT_FLT_OPTIONS_CRC_CHECK_MASK; + } + else + { + regval &= ~PCKT_FLT_OPTIONS_CRC_CHECK_MASK; + } + + /* Writes the PCKT_FLT_OPTIONS register value */ + + ret = spirit_reg_write(spirit, PCKT_FLT_OPTIONS_BASE, ®val, 1); + } + + return ret; +} diff --git a/drivers/wireless/spirit/lib/spirit_radio.c b/drivers/wireless/spirit/lib/spirit_radio.c index e5267305d0..3c615506de 100644 --- a/drivers/wireless/spirit/lib/spirit_radio.c +++ b/drivers/wireless/spirit/lib/spirit_radio.c @@ -3,12 +3,12 @@ * 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 + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 * - * Adapted for NuttX by: - * Author: Gregory Nutt + * Adapted for NuttX by: + * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -48,6 +48,7 @@ #include "spirit_config.h" #include "spirit_types.h" #include "spirit_management.h" +#include "spirit_calibration.h" #include "spirit_radio.h" #include "spirit_spi.h" @@ -129,6 +130,14 @@ static const float g_power_factors[5][6] = {-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 +}; + /****************************************************************************** * Private Functions ******************************************************************************/ @@ -559,6 +568,87 @@ enum xtal_flag_e spirit_radio_get_xtalflag(FAR struct spirit_library_s *spirit) 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 * @@ -687,7 +777,7 @@ int spirit_radio_set_band(FAR struct spirit_library_s *spirit, * Returns the operating band. * * Input Parameters: - * spirit - Reference to a Spirit library state structure instance + * spirit - Reference to a Spirit library state structure instance * * Returned Value: * BandSelect Settled band. This returned value may be one of the @@ -728,6 +818,160 @@ enum spirit_bandselect_e } } +/****************************************************************************** + * 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; + + /* Reads 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_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) +{ + /* Writes 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; + + /* Reads the CHNUM register and return the value */ + + (void)spirit_reg_read(spirit, CHNUM_BASE, ®val, 1); + return regval; +} + +/****************************************************************************** + * 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]; + + /* Reads 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 * @@ -749,8 +993,153 @@ enum spirit_bandselect_e int spirit_radio_set_basefrequency(FAR struct spirit_library_s *spirit, uint32_t fbase) { -#warning Missing logic - return -ENOSYS; + 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; + + /* Reads 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; } /****************************************************************************** @@ -1123,7 +1512,7 @@ uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, * is in the correct range [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dBm. * * Returned Value: - * None. + * Zero (OK) on success. A negated errno value is returned on any failure. * ******************************************************************************/ @@ -1153,6 +1542,86 @@ int spirit_radio_set_palevel(FAR struct spirit_library_s *spirit, return spirit_reg_write(spirit, address, &level, 1); } +/****************************************************************************** + * 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)); + + /* Reads 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; + + /* Reads 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 * diff --git a/drivers/wireless/spirit/lib/spirit_spi.c b/drivers/wireless/spirit/lib/spirit_spi.c index 079210e5d5..704e4ba5b1 100644 --- a/drivers/wireless/spirit/lib/spirit_spi.c +++ b/drivers/wireless/spirit/lib/spirit_spi.c @@ -290,7 +290,7 @@ int spirit_command(FAR struct spirit_library_s *spirit, uint8_t cmd) } /****************************************************************************** - * Name: spirt_fifo_read + * Name: spirit_fifo_read * * Description: * Read data from RX FIFO @@ -306,8 +306,8 @@ int spirit_command(FAR struct spirit_library_s *spirit, uint8_t cmd) * ******************************************************************************/ -int spirt_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, - unsigned int buflen) +int spirit_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, + unsigned int buflen) { uint8_t header[2]; uint8_t status[2]; @@ -342,7 +342,7 @@ int spirt_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, } /****************************************************************************** - * Name: spirt_fifo_write + * Name: spirit_fifo_write * * Description: * Write data into TX FIFO. @@ -358,8 +358,8 @@ int spirt_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, * ******************************************************************************/ -int spirt_fifo_write(FAR struct spirit_library_s *spirit, - FAR const uint8_t *buffer, unsigned int buflen) +int spirit_fifo_write(FAR struct spirit_library_s *spirit, + FAR const uint8_t *buffer, unsigned int buflen) { uint8_t header[2]; uint8_t status[2];