mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/ng_at86rf2xx: Clean up state transition code.
- Force TRX_OFF before SLEEP - Add function to reset the state machine - Reset state machine after hardware reset during initialization - Get rid of redundant at86rf2xx_get_state
This commit is contained in:
parent
68053870e3
commit
0e1f8f1efe
@ -346,14 +346,6 @@ void ng_at86rf2xx_set_max_retries(ng_at86rf2xx_t *dev, uint8_t max);
|
||||
*/
|
||||
void ng_at86rf2xx_set_option(ng_at86rf2xx_t *dev, uint16_t option, bool state);
|
||||
|
||||
/**
|
||||
* @brief Get the given devices current internal state
|
||||
*
|
||||
* @param[in] dev device to get state of
|
||||
* @return the current state of the given device
|
||||
*/
|
||||
uint8_t ng_at86rf2xx_get_state(ng_at86rf2xx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set the state of the given device (trigger a state change)
|
||||
*
|
||||
@ -362,6 +354,17 @@ uint8_t ng_at86rf2xx_get_state(ng_at86rf2xx_t *dev);
|
||||
*/
|
||||
void ng_at86rf2xx_set_state(ng_at86rf2xx_t *dev, uint8_t state);
|
||||
|
||||
/**
|
||||
* @brief Reset the internal state machine to TRX_OFF mode.
|
||||
*
|
||||
* This will force a transition to TRX_OFF regardless of whether the transceiver
|
||||
* is currently busy sending or receiving. This function is used to get back to
|
||||
* a known state during driver initialization.
|
||||
*
|
||||
* @param[in] dev device to operate on
|
||||
*/
|
||||
void ng_at86rf2xx_reset_state_machine(ng_at86rf2xx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Convenience function for simply sending data
|
||||
*
|
||||
|
@ -92,10 +92,16 @@ void ng_at86rf2xx_reset(ng_at86rf2xx_t *dev)
|
||||
eui64_t addr_long;
|
||||
#endif
|
||||
|
||||
/* wake from sleep in case radio is sleeping */
|
||||
gpio_clear(dev->sleep_pin);
|
||||
/* trigger hardware reset */
|
||||
gpio_clear(dev->reset_pin);
|
||||
hwtimer_wait(HWTIMER_TICKS(RESET_DELAY));
|
||||
gpio_set(dev->reset_pin);
|
||||
|
||||
/* Reset state machine to ensure a known state */
|
||||
ng_at86rf2xx_reset_state_machine(dev);
|
||||
|
||||
/* reset options and sequence number */
|
||||
dev->seq_nr = 0;
|
||||
dev->options = 0;
|
||||
@ -206,7 +212,7 @@ void ng_at86rf2xx_tx_prepare(ng_at86rf2xx_t *dev)
|
||||
|
||||
/* make sure ongoing transmissions are finished */
|
||||
do {
|
||||
state = ng_at86rf2xx_get_state(dev);
|
||||
state = ng_at86rf2xx_get_status(dev);
|
||||
}
|
||||
while (state == NG_AT86RF2XX_STATE_BUSY_RX_AACK);
|
||||
dev->idle_state = state;
|
||||
|
@ -334,43 +334,68 @@ void ng_at86rf2xx_set_option(ng_at86rf2xx_t *dev, uint16_t option, bool state)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ng_at86rf2xx_get_state(ng_at86rf2xx_t *dev)
|
||||
{
|
||||
uint8_t status = ng_at86rf2xx_get_status(dev);
|
||||
return (status & 0x1f);
|
||||
}
|
||||
|
||||
static inline void _set_state(ng_at86rf2xx_t *dev, uint8_t state)
|
||||
{
|
||||
ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__TRX_STATE, state);
|
||||
while (ng_at86rf2xx_get_state(dev) != state);
|
||||
while (ng_at86rf2xx_get_status(dev) != state);
|
||||
}
|
||||
|
||||
static inline void _force_trx_off(ng_at86rf2xx_t *dev)
|
||||
{
|
||||
ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__TRX_STATE, NG_AT86RF2XX_TRX_STATE__FORCE_TRX_OFF);
|
||||
while (ng_at86rf2xx_get_status(dev) != NG_AT86RF2XX_STATE_TRX_OFF);
|
||||
}
|
||||
|
||||
void ng_at86rf2xx_set_state(ng_at86rf2xx_t *dev, uint8_t state)
|
||||
{
|
||||
uint8_t old_state = ng_at86rf2xx_get_state(dev);
|
||||
uint8_t old_state = ng_at86rf2xx_get_status(dev);
|
||||
|
||||
if (state == old_state) {
|
||||
return;
|
||||
}
|
||||
/* make sure there is no ongoing transmission */
|
||||
/* make sure there is no ongoing transmission, or state transition already
|
||||
* in progress */
|
||||
while (old_state == NG_AT86RF2XX_STATE_BUSY_RX_AACK ||
|
||||
old_state == NG_AT86RF2XX_STATE_BUSY_TX_ARET) {
|
||||
old_state = ng_at86rf2xx_get_state(dev);
|
||||
old_state == NG_AT86RF2XX_STATE_BUSY_TX_ARET ||
|
||||
old_state == NG_AT86RF2XX_STATE_IN_PROGRESS) {
|
||||
old_state = ng_at86rf2xx_get_status(dev);
|
||||
}
|
||||
|
||||
/* we need to go via PLL_ON if we are moving between RX_AACK_ON <-> TX_ARET_ON */
|
||||
if ((old_state == NG_AT86RF2XX_STATE_RX_AACK_ON &&
|
||||
state == NG_AT86RF2XX_STATE_TX_ARET_ON) ||
|
||||
(old_state == NG_AT86RF2XX_STATE_TX_ARET_ON &&
|
||||
state == NG_AT86RF2XX_STATE_RX_AACK_ON)) {
|
||||
_set_state(dev, NG_AT86RF2XX_STATE_PLL_ON);
|
||||
}
|
||||
/* check if we need to wake up from sleep mode */
|
||||
if (old_state == NG_AT86RF2XX_STATE_SLEEP) {
|
||||
else if (old_state == NG_AT86RF2XX_STATE_SLEEP) {
|
||||
DEBUG("at86rf2xx: waking up from sleep mode\n");
|
||||
gpio_clear(dev->sleep_pin);
|
||||
while (ng_at86rf2xx_get_state(dev) != NG_AT86RF2XX_STATE_TRX_OFF);
|
||||
while (ng_at86rf2xx_get_status(dev) != NG_AT86RF2XX_STATE_TRX_OFF);
|
||||
}
|
||||
/* go to neutral TRX_OFF state */
|
||||
_set_state(dev, NG_AT86RF2XX_STATE_TRX_OFF);
|
||||
if (state == NG_AT86RF2XX_STATE_RX_AACK_ON ||
|
||||
state == NG_AT86RF2XX_STATE_TX_ARET_ON) {
|
||||
_set_state(dev, state);
|
||||
} else if (state == NG_AT86RF2XX_STATE_SLEEP) {
|
||||
|
||||
if (state == NG_AT86RF2XX_STATE_SLEEP) {
|
||||
/* First go to TRX_OFF */
|
||||
_force_trx_off(dev);
|
||||
/* Go to SLEEP mode from TRX_OFF */
|
||||
gpio_set(dev->sleep_pin);
|
||||
while (ng_at86rf2xx_get_state(dev) != NG_AT86RF2XX_STATE_SLEEP);
|
||||
} else {
|
||||
_set_state(dev, state);
|
||||
}
|
||||
}
|
||||
|
||||
void ng_at86rf2xx_reset_state_machine(ng_at86rf2xx_t *dev)
|
||||
{
|
||||
uint8_t old_state;
|
||||
|
||||
/* Wake up */
|
||||
gpio_clear(dev->sleep_pin);
|
||||
|
||||
/* Wait for any state transitions to complete before forcing TRX_OFF */
|
||||
do {
|
||||
old_state = ng_at86rf2xx_get_status(dev);
|
||||
} while (old_state == NG_AT86RF2XX_STATE_IN_PROGRESS);
|
||||
|
||||
_force_trx_off(dev);
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ static int _set_state(ng_at86rf2xx_t *dev, ng_netconf_state_t state)
|
||||
|
||||
ng_netconf_state_t _get_state(ng_at86rf2xx_t *dev)
|
||||
{
|
||||
switch (ng_at86rf2xx_get_state(dev)) {
|
||||
switch (ng_at86rf2xx_get_status(dev)) {
|
||||
case NG_AT86RF2XX_STATE_SLEEP:
|
||||
return NETCONF_STATE_SLEEP;
|
||||
case NG_AT86RF2XX_STATE_BUSY_RX_AACK:
|
||||
@ -691,7 +691,7 @@ static void _isr_event(ng_netdev_t *device, uint32_t event_type)
|
||||
|
||||
/* read (consume) device status */
|
||||
irq_mask = ng_at86rf2xx_reg_read(dev, NG_AT86RF2XX_REG__IRQ_STATUS);
|
||||
state = ng_at86rf2xx_get_state(dev);
|
||||
state = ng_at86rf2xx_get_status(dev);
|
||||
|
||||
if (irq_mask & NG_AT86RF2XX_IRQ_STATUS_MASK__RX_START) {
|
||||
dev->event_cb(NETDEV_EVENT_RX_STARTED, NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user