1
0
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:
Joakim Gebart 2015-07-16 20:54:50 +02:00
parent 68053870e3
commit 0e1f8f1efe
4 changed files with 65 additions and 31 deletions

View File

@ -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
*

View File

@ -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;

View File

@ -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);
}

View File

@ -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);