/** * @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 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); #ifndef NO_32KHZ_CRYSTAL /* Do not set to SLEEP to keep clock source for symbol counter alive. */ trx_status = set_trx_state(CMD_SLEEP); #else /* Pretend that trx is in SLEEP - for this function only. */ trx_status = TRX_SLEEP; #endif #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 stb_restart(); #endif return MAC_SUCCESS; } else { /* State could not be set due to TAL_BUSY state. */ return TAL_BUSY; } }
/** * \brief Reset transceiver * * \return MAC_SUCCESS if the transceiver state is changed to TRX_OFF * FAILURE otherwise */ static retval_t trx_reset(void) { tal_trx_status_t trx_status; uint8_t poll_counter = 0; /* trx might sleep, so wake it up */ PAL_SLP_TR_LOW(); pal_timer_delay(SLEEP_TO_TRX_OFF_TYP_US); /* Apply reset pulse */ PAL_RST_LOW(); pal_timer_delay(RST_PULSE_WIDTH_US); PAL_RST_HIGH(); /* verify that trx has reached TRX_OFF */ do { /* Wait a short time interval. */ pal_timer_delay(TRX_POLL_WAIT_TIME_US); trx_status = (tal_trx_status_t)pal_trx_bit_read(SR_TRX_STATUS); /* Wait not more than max. value of TR2. */ if (poll_counter == SLEEP_TO_TRX_OFF_ATTEMPTS) { #if (_DEBUG_ > 0) Assert( "MAX Attempts to switch to TRX_OFF state reached" == 0); #endif return FAILURE; } poll_counter++; } while (trx_status != TRX_OFF); tal_trx_status = TRX_OFF; #ifdef STB_ON_SAL #if (SAL_TYPE == AT86RF2xx) stb_restart(); #endif #endif return MAC_SUCCESS; }
/** * @brief Resets TAL state machine and sets the default PIB values if requested * * @param set_default_pib Defines whether PIB values need to be set * to its default values * * @return MAC_SUCCESS if the transceiver state is changed to TRX_OFF * FAILURE otherwise */ retval_t tal_reset(bool set_default_pib) { /* * Do the reset stuff. * Set the default PIBs depending on the given parameter set_default_pib. * Do NOT generate random seed again. */ if (internal_tal_reset(set_default_pib) != MAC_SUCCESS) { return FAILURE; } #if (NUMBER_OF_TAL_TIMERS > 0) /* Clear all running TAL timers. */ { uint8_t timer_id; ENTER_CRITICAL_REGION(); for (timer_id = TAL_FIRST_TIMER_ID; timer_id <= TAL_LAST_TIMER_ID; timer_id++) { pal_timer_stop(timer_id); } LEAVE_CRITICAL_REGION(); } #endif /* Clear TAL Incoming Frame queue and free used buffers. */ while (tal_incoming_frame_queue.size > 0) { buffer_t *frame = qmm_queue_remove(&tal_incoming_frame_queue, NULL); if (NULL != frame) { bmm_buffer_free(frame); } } #ifdef ENABLE_TFA tfa_reset(set_default_pib); #endif /* * Configure interrupt handling. Clear all pending interrupts. * Handlers have been installed in tal_init(), and are never * uninstalled. */ pal_trx_irq_flag_clr_rx_end(); pal_trx_irq_flag_clr_tx_end(); #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) pal_trx_irq_flag_clr_tstamp(); #endif /* (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */ pal_trx_irq_flag_clr_awake(); /* * To make sure that the CSMA seed is properly set within the transceiver, * put the trx to sleep briefly and wake it up again. */ tal_trx_sleep(SLEEP_MODE_1); tal_trx_wakeup(); #ifdef ENABLE_FTN_PLL_CALIBRATION { /* Handle PLL calibration and filter tuning. */ retval_t timer_status; /* Calibration timer has already been stopped within this function. */ /* 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 */ #ifdef STB_ON_SAL stb_restart(); #endif return MAC_SUCCESS; }
/** * @brief Reset transceiver * * @return MAC_SUCCESS if the transceiver state is changed to TRX_OFF * FAILURE otherwise */ static retval_t trx_reset(void) { tal_trx_status_t trx_status; uint8_t poll_counter = 0; #if (EXTERN_EEPROM_AVAILABLE == 1) uint8_t xtal_trim_value; #endif /* Get trim value for 16 MHz xtal; needs to be done before reset due to board constraints. */ #if (EXTERN_EEPROM_AVAILABLE == 1) pal_ps_get(EXTERN_EEPROM, EE_XTAL_TRIM_ADDR, 1, &xtal_trim_value); #endif /* trx might sleep, so wake it up */ PAL_SLP_TR_LOW(); pal_timer_delay(SLEEP_TO_TRX_OFF_TYP_US); /* Apply reset pulse */ PAL_RST_LOW(); pal_timer_delay(RST_PULSE_WIDTH_US); PAL_RST_HIGH(); /* verify that trx has reached TRX_OFF */ do { /* Wait a short time interval. */ pal_timer_delay(TRX_POLL_WAIT_TIME_US); trx_status = (tal_trx_status_t)pal_trx_bit_read(SR_TRX_STATUS); /* Wait not more than max. value of TR2. */ if (poll_counter == SLEEP_TO_TRX_OFF_ATTEMPTS) { #if (DEBUG > 0) pal_alert(); #endif return FAILURE; } poll_counter++; } while (trx_status != TRX_OFF); tal_trx_status = TRX_OFF; /* * Write 16MHz xtal trim value to trx. * It's only necessary if it differs from the reset value. */ #if (EXTERN_EEPROM_AVAILABLE == 1) if (xtal_trim_value != 0x00) { pal_trx_bit_write(SR_XTAL_TRIM, xtal_trim_value); } #endif #ifdef STB_ON_SAL #if (SAL_TYPE == AT86RF2xx) stb_restart(); #endif #endif return MAC_SUCCESS; }