Beispiel #1
0
/**
 * @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;
    }
}
Beispiel #2
0
/*
 * \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;
	}
}
Beispiel #3
0
/**
 * \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;
}
Beispiel #4
0
/**
 * @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;
}