/** * @brief Sets the transceiver to sleep * * This function sets the transceiver to sleep state. * * @param mode Defines sleep mode of transceiver SLEEP or PHY_TRX_OFF) * * @return TAL_BUSY - The transceiver is busy in TX or RX * MAC_SUCCESS - The transceiver is put to sleep * TAL_TRX_ASLEEP - The transceiver is already asleep * MAC_INVALID_PARAMETER - The specified sleep mode is not supported */ retval_t tal_trx_sleep(sleep_mode_t mode) { tal_trx_status_t trx_status; /* Current transceiver only supports SLEEP_MODE_1 mode. */ if (SLEEP_MODE_1 != mode) { return MAC_INVALID_PARAMETER; } if (tal_trx_status == TRX_SLEEP) { return TAL_TRX_ASLEEP; } /* Device can be put to sleep only when the TAL is in IDLE state. */ if (TAL_IDLE != tal_state) { return TAL_BUSY; } tal_rx_on_required = false; /* * First set trx to TRX_OFF. * If trx is busy, like ACK transmission, do not interrupt it. */ do { trx_status = set_trx_state(CMD_TRX_OFF); } while (trx_status != TRX_OFF); pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_SLEEP); trx_status = set_trx_state(CMD_SLEEP); #ifdef ENABLE_FTN_PLL_CALIBRATION /* * Stop the calibration timer now. * The timer will be restarted during wake-up. */ pal_timer_stop(TAL_CALIBRATION); #endif /* ENABLE_FTN_PLL_CALIBRATION */ if (trx_status == TRX_SLEEP) { #ifdef STB_ON_SAL #if (SAL_TYPE == AT86RF2xx) stb_restart(); #endif #endif return MAC_SUCCESS; } else { /* State could not be set due to TAL_BUSY state. */ return TAL_BUSY; } }
/** * @brief MAC function to put the radio to sleep mode */ void mac_trx_init_sleep(void) { /* If the radio is not sleeping, it is put to sleep */ if (RADIO_AWAKE == mac_radio_sleep_state) { pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_SLEEP); #ifdef ENABLE_DEEP_SLEEP if (MAC_SUCCESS == tal_trx_sleep(DEEP_SLEEP_MODE)) #else if (MAC_SUCCESS == tal_trx_sleep(SLEEP_MODE_1)) #endif { mac_radio_sleep_state = RADIO_SLEEPING; } else { pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_AWAKE); } } }
/** * @brief MAC function to wake-up the radio from sleep state */ void mac_trx_wakeup(void) { /* If the radio is sleeping, it is woken-up */ if (RADIO_SLEEPING == mac_radio_sleep_state) { if (FAILURE != tal_trx_wakeup()) { pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_AWAKE); mac_radio_sleep_state = RADIO_AWAKE; } } }
/* * @brief Internal MAC reset function * * This function resets the MAC variables, stops all running timers and * initializes the PIBs. * * @param init_pib Boolean indicates whether PIB attributes shall be * initialized or not. * * @return Success or failure status */ static uint8_t mac_reset(uint8_t init_pib) { uint8_t status = MAC_DISABLE_TRX_FAILURE; /* * Transceiver is going to stop giving out clock for some time * so change to internal clock */ pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_SLEEP); /* Reset TAL */ status = tal_reset(init_pib); /* Transceiver is now giving out clock, switch back to external clock */ pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_AWAKE); mac_soft_reset(init_pib); return status; }
/** * @brief Wakes up the transceiver from sleep * * This function awakes the transceiver from sleep state. * * @return TAL_TRX_AWAKE - The transceiver is already awake * MAC_SUCCESS - The transceiver is woken up from sleep * FAILURE - The transceiver did not wake-up from sleep */ retval_t tal_trx_wakeup(void) { tal_trx_status_t trx_status; if (tal_trx_status != TRX_SLEEP) { return TAL_TRX_AWAKE; } #ifdef ENABLE_FTN_PLL_CALIBRATION { retval_t timer_status; /* * Calibration timer has been stopped when going to sleep, * so it needs to be restarted. * All other state changes except via sleep that are ensuring * implicit filter tuning and pll calibration are ignored. * Therefore the calibration timer needs to be restarted for * to those cases. * This is handled in file tal.c. */ /* Start periodic calibration timer.*/ timer_status = pal_timer_start(TAL_CALIBRATION, TAL_CALIBRATION_TIMEOUT_US, TIMEOUT_RELATIVE, (FUNC_PTR)calibration_timer_handler_cb, NULL); if (timer_status != MAC_SUCCESS) { ASSERT("PLL calibration timer start problem" == 0); } } #endif /* ENABLE_FTN_PLL_CALIBRATION */ trx_status = set_trx_state(CMD_TRX_OFF); if (trx_status == TRX_OFF) { pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_AWAKE); return MAC_SUCCESS; } else { return FAILURE; } }
/** * @brief Sets the transceiver to sleep * * This function sets the transceiver to sleep state. * * @param mode Defines sleep mode of transceiver SLEEP or PHY_TRX_OFF) * * @return TAL_BUSY - The transceiver is busy in TX or RX * MAC_SUCCESS - The transceiver is put to sleep * TAL_TRX_ASLEEP - The transceiver is already asleep * MAC_INVALID_PARAMETER - The specified sleep mode is not supported */ retval_t tal_trx_sleep(sleep_mode_t mode) { tal_trx_status_t trx_status; /* Current transceiver only supports SLEEP_MODE_1 mode. */ if (SLEEP_MODE_1 != mode) { return MAC_INVALID_PARAMETER; } if (tal_trx_status == TRX_SLEEP) { return TAL_TRX_ASLEEP; } /* Device can be put to sleep only when the TAL is in IDLE state. */ if (TAL_IDLE != tal_state) { return TAL_BUSY; } /* * First set trx to TRX_OFF. * If trx is busy, like ACK transmission, do not interrupt it. */ do { trx_status = set_trx_state(CMD_TRX_OFF); } while (trx_status != TRX_OFF); pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_SLEEP); trx_status = set_trx_state(CMD_TRX_SLEEP); if (trx_status == TRX_SLEEP) { return MAC_SUCCESS; } else { /* State could not be set due to TAL_BUSY state. */ return TAL_BUSY; } }
/** * @brief Wakes up the transceiver from sleep * * This function awakes the transceiver from sleep state. * * @return TAL_TRX_AWAKE - The transceiver is already awake * MAC_SUCCESS - The transceiver is woken up from sleep * FAILURE - The transceiver did not wake-up from sleep */ retval_t tal_trx_wakeup(void) { tal_trx_status_t trx_status; if (tal_trx_status != TRX_SLEEP) { return TAL_TRX_AWAKE; } trx_status = set_trx_state(CMD_TRX_OFF); if (trx_status == TRX_OFF) { pal_timer_source_select(TMR_CLK_SRC_DURING_TRX_AWAKE); return MAC_SUCCESS; } else { return FAILURE; } }