Spirit: Add a function to wait for a state change with a timeout.

This commit is contained in:
Gregory Nutt 2017-08-01 10:31:12 -06:00
parent bd027b9019
commit ceca6c69a8
6 changed files with 123 additions and 115 deletions

View File

@ -53,7 +53,6 @@
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <nuttx/clock.h>
#include <nuttx/fs/fs.h>
#include <nuttx/mm/iob.h>
#include <nuttx/spi/spi.h>
@ -151,8 +150,6 @@ struct spirit_driver_s
static void spirit_lock(FAR struct spirit_driver_s *priv);
#define spirit_unlock(priv) sem_post(&priv->exclsem);
static int spirit_waitstatus(FAR struct spirit_library_s *spirit,
enum spirit_state_e state, unsigned int msec);
static int spirit_set_readystate(FAR struct spirit_driver_s *priv);
/* TX-related logic */
@ -299,7 +296,7 @@ static struct pktbasic_addr_s g_addrinit =
****************************************************************************/
/****************************************************************************
* Name: spirit_waitstatus
* Name: spirit_lock
*
* Description:
* Get exclusive access to the driver instance and to the spirit library.
@ -320,67 +317,6 @@ static void spirit_lock(FAR struct spirit_driver_s *priv)
}
}
/****************************************************************************
* Name: spirit_waitstatus
*
* Description:
* Poll until the Spirit status is the requested value or until a timeout
* occurs.
*
* Parameters:
* spirit - Reference to a Spirit library state structure instance
* state - That that we are waiting for.
* msec - Timeout in millisedonds
*
* Returned Value:
* OK on success; a negated errno on a timeout
*
* Assumptions:
* We have exclusive access to the driver state and to the spirit library.
*
****************************************************************************/
static int spirit_waitstatus(FAR struct spirit_library_s *spirit,
enum spirit_state_e state, unsigned int msec)
{
systime_t start;
unsigned int ticks;
unsigned int elapsed;
int ret;
/* MSEC to clock ticks (add one to make sure we wait at least requested
* timeout)
*/
ticks = MSEC2TICK(msec);
if (ticks == 0)
{
/* The timeout is below the current timer resolution */
ticks = 1;
}
/* The time that we started the wait */
start = clock_systimer();
/* Loop until the status change occurs (or the wait times out) */
do
{
ret = spirit_update_status(spirit);
if (ret < 0)
{
return ret;
}
elapsed = clock_systimer() - start;
}
while (spirit->u.state.MC_STATE != state && elapsed <= ticks);
return (spirit->u.state.MC_STATE == state) ? OK : -ETIMEDOUT;
}
/****************************************************************************
* Name: spirit_set_readystate
*

View File

@ -49,14 +49,12 @@
* Example:
*
* uint8_t caldata;
* int ret;
*
* spirit_calib_enable_vco(spirit, S_ENABLE);
* spirit_command(spirit, CMD_LOCKTX);
*
* while(spirit->state.MC_STATE != MC_STATE_LOCK)
* {
* (void)spirit_update_status(spirit);
* }
* ret = spirit_waitstatus(spirit, MC_STATE_LOCK, 5000);
*
* caldata = spirit_calib_get_vcotxcal(spirit);
* spirit_calib_set_vcotxcal(spirit, caldata);

View File

@ -197,6 +197,29 @@ int spirit_fifo_write(FAR struct spirit_library_s *spirit,
int spirit_update_status(FAR struct spirit_library_s *spirit);
/****************************************************************************
* Name: spirit_waitstatus
*
* Description:
* Poll until the Spirit status is the requested value or until a timeout
* occurs.
*
* Parameters:
* spirit - Reference to a Spirit library state structure instance
* state - That that we are waiting for.
* msec - Timeout in millisedonds
*
* Returned Value:
* OK on success; a negated errno on a timeout
*
* Assumptions:
* We have exclusive access to the driver state and to the spirit library.
*
****************************************************************************/
int spirit_waitstatus(FAR struct spirit_library_s *spirit,
enum spirit_state_e state, unsigned int msec);
#ifdef __cplusplus
}
#endif

View File

@ -339,15 +339,11 @@ uint8_t spirit_managment_wavco_calibration(FAR struct spirit_library_s *spirit)
return ret;
}
do
ret = spirit_waitstatus(spirit, MC_STATE_READY, 5000);
if (ret < 0)
{
ret = spirit_update_status(spirit);
if (ret < 0)
{
return ret;
}
return ret;
}
while (spirit->u.state.MC_STATE != MC_STATE_READY);
ret = spirit_command(spirit, CMD_LOCKRX);
if (ret < 0)

View File

@ -176,15 +176,7 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit,
uint8_t regval;
uint8_t value;
int ret;
/* Check the parameters */
DEBUGASSERT(IS_FREQUENCY_BAND(radioinit->base_frequency));
DEBUGASSERT(IS_MODULATION_SELECTED(radioinit->modselect));
DEBUGASSERT(IS_DATARATE(radioinit->datarate));
DEBUGASSERT(IS_FREQUENCY_OFFSET(radioinit->foffset, spirit->xtal_frequency));
DEBUGASSERT(IS_CHANNEL_SPACE(radioinit->chspace, spirit->xtal_frequency));
DEBUGASSERT(IS_F_DEV(radioinit->freqdev, spirit->xtal_frequency));
int i;
/* Workaround for Vtune */
@ -202,6 +194,15 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit,
offset = (int32_t)(((float)radioinit->foffset * radioinit->base_frequency) /
PPM_FACTOR);
/* Check the parameters */
DEBUGASSERT(IS_FREQUENCY_BAND(radioinit->base_frequency));
DEBUGASSERT(IS_MODULATION_SELECTED(radioinit->modselect));
DEBUGASSERT(IS_DATARATE(radioinit->datarate));
DEBUGASSERT(IS_FREQUENCY_OFFSET(offset, spirit->xtal_frequency));
DEBUGASSERT(IS_CHANNEL_SPACE(radioinit->chspace, spirit->xtal_frequency));
DEBUGASSERT(IS_F_DEV(radioinit->freqdev, spirit->xtal_frequency));
/* Disable the digital, ADC, SMPS reference clock divider if fXO > 24MHz or
* fXO < 26MHz
*/
@ -212,23 +213,17 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit,
return ret;
}
do
/* Delay for state transition */
for (i = 0; i != 0xff; i++);
/* Wait for the device to enter STANDBY */
ret = spirit_waitstatus(spirit, MC_STATE_STANDBY, 5000);
if (ret < 0)
{
volatile uint8_t i;
/* Delay for state transition */
for (i = 0; i != 0xff; i++);
/* Read the MC_STATUS register */
ret = spirit_update_status(spirit);
if (ret < 0)
{
return ret;
}
return ret;
}
while (spirit->u.state.MC_STATE != MC_STATE_STANDBY);
if (spirit->xtal_frequency < DOUBLE_XTAL_THR)
{
@ -254,23 +249,17 @@ int spirit_radio_initialize(FAR struct spirit_library_s *spirit,
return ret;
}
do
/* Delay for state transition */
for (i = 0; i != 0xff; i++);
/* Make sure that the device becomes READY */
ret = spirit_waitstatus(spirit, MC_STATE_READY, 5000);
if (ret < 0)
{
volatile uint8_t i;
/* Delay for state transition */
for (i = 0; i != 0xff; i++);
/* Read the MC_STATUS register */
ret = spirit_update_status(spirit);
if (ret < 0)
{
return ret;
}
return ret;
}
while (spirit->u.state.MC_STATE != MC_STATE_READY);
/* Calculates the FC_OFFSET parameter and cast as signed int: offset =
* (Fxtal/2^18)*FC_OFFSET

View File

@ -47,7 +47,9 @@
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/clock.h>
#include <nuttx/spi/spi.h>
#include "spirit_regs.h"
@ -534,3 +536,67 @@ int spirit_update_status(FAR struct spirit_library_s *spirit)
return spirit_reg_read(spirit, MC_STATE1_BASE, &regval, 1);
}
/****************************************************************************
* Name: spirit_waitstatus
*
* Description:
* Poll until the Spirit status is the requested value or until a timeout
* occurs.
*
* Parameters:
* spirit - Reference to a Spirit library state structure instance
* state - That that we are waiting for.
* msec - Timeout in millisedonds
*
* Returned Value:
* OK on success; a negated errno on a timeout
*
* Assumptions:
* We have exclusive access to the driver state and to the spirit library.
*
****************************************************************************/
int spirit_waitstatus(FAR struct spirit_library_s *spirit,
enum spirit_state_e state, unsigned int msec)
{
systime_t start;
systime_t ticks;
systime_t elapsed;
int ret;
/* Convert the MSEC timedelay to clock ticks, making sure that the
* resulting delay in ticks is greater than or equal to the requested time
* in MSEC.
*
* REVIST: If USEC_PER_TICK and 'msec' are large, then the second
* computation may overflow!
*/
#if (MSEC_PER_TICK * USEC_PER_MSEC) == USEC_PER_TICK
ticks = (msec + (MSEC_PER_TICK - 1)) / MSEC_PER_TICK;
#else
ticks = ((systime_t)msec * USEC_PER_MSEC + (USEC_PER_TICK - 1)) /
USEC_PER_TICK;
#endif
/* The time that we started the wait */
start = clock_systimer();
/* Loop until the status change occurs (or the wait times out) */
do
{
ret = spirit_update_status(spirit);
if (ret < 0)
{
return ret;
}
elapsed = clock_systimer() - start;
}
while (spirit->u.state.MC_STATE != state && elapsed <= ticks);
return (spirit->u.state.MC_STATE == state) ? OK : -ETIMEDOUT;
}