Spirit: Add a function to wait for a state change with a timeout.
This commit is contained in:
parent
bd027b9019
commit
ceca6c69a8
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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, ®val, 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user