Exemple #1
0
/**
 * \brief Switches the PLL on
 * \ingroup group_tal_state_machine_212b
 */
static void switch_pll_on(void)
{
	trx_irq_reason_t irq_status;
	uint8_t poll_counter = 0;

	/* Check if trx is in TRX_OFF; only from PLL_ON the following procedure
	 * is applicable */
	if (trx_bit_read(SR_TRX_STATUS) != TRX_OFF) {
		Assert(
				"Switch PLL_ON failed, because trx is not in TRX_OFF" ==
				0);
		return;
	}

	trx_reg_read(RG_IRQ_STATUS); /* clear PLL lock bit */
	/* Switch PLL on */
	trx_reg_write(RG_TRX_STATE, CMD_PLL_ON);

	/* Check if PLL has been locked. */
	do {
		irq_status = (trx_irq_reason_t)trx_reg_read(RG_IRQ_STATUS);

		if (irq_status & TRX_IRQ_0_PLL_LOCK) {
			return; /* PLL is locked now */
		}

		/* Wait a time interval of typical value for timer TR4. */
		pal_timer_delay(TRX_OFF_TO_PLL_ON_TIME_US);

		poll_counter++;
	} while (poll_counter < PLL_LOCK_ATTEMPTS);
}
Exemple #2
0
/**
 * \brief Initializes the transceiver
 *
 * This function is called to initialize the transceiver.
 *
 * \return MAC_SUCCESS  if the transceiver state is changed to TRX_OFF and the
 *                 current device part number and version number are correct;
 *         FAILURE otherwise
 */
static retval_t trx_init(void)
{
	tal_trx_status_t trx_status;
	uint8_t poll_counter = 0;

	TRX_RST_HIGH();
	TRX_SLP_TR_LOW();

	/* Wait typical time of timer TR1. */
	pal_timer_delay(P_ON_TO_CLKM_AVAILABLE_TYP_US);

	/* Apply reset pulse */
	TRX_RST_LOW();
	pal_timer_delay(RST_PULSE_WIDTH_US);
	TRX_RST_HIGH();

#if !(defined FPGA_EMULATION)
	do {
		/* Wait not more than max. value of TR1. */
		if (poll_counter == P_ON_TO_CLKM_ATTEMPTS) {
			return FAILURE;
		}

		/* Wait a short time interval. */
		pal_timer_delay(TRX_POLL_WAIT_TIME_US);
		poll_counter++;

		/* Check if AT86RF233 is connected; omit manufacturer id check
		**/
	} while (trx_reg_read(RG_PART_NUM) != PART_NUM_AT86RF233);
#endif  /* !defined FPGA_EMULATION */

	/* Verify that TRX_OFF can be written */
	trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);

	/* Verify that the trx has reached TRX_OFF. */
	poll_counter = 0;
	do {
		/* Wait a short time interval. */
		pal_timer_delay(TRX_POLL_WAIT_TIME_US);

		trx_status = /*(tal_trx_status_t)*/ trx_bit_read(SR_TRX_STATUS);

		/* Wait not more than max. value of TR15. */
		if (poll_counter == P_ON_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;

	return MAC_SUCCESS;
}
/**
 * @brief Frame reception
 *
 */
void radio_receive_frame(void)
{

uint8_t len, lqi, crc_fail;
int8_t ed;

    /* @todo add RSSI_BASE_VALUE to get a dBm value */
    ed = (int8_t)trx_reg_read(RG_PHY_ED_LEVEL);
    len = trx_frame_read(radiostatus.rxframe, radiostatus.rxframesz, &lqi);
    len &= ~0x80;

    #if defined(SR_RX_CRC_VALID)
        crc_fail = trx_bit_read(SR_RX_CRC_VALID) ? 0 : 1;
    #else
        uint8_t *frm, i;
        uint16_t crc;
        crc = 0;
        frm = radiostatus.rxframe;
        for (i=0; i < len; i++)
        {
            crc = CRC_CCITT_UPDATE(crc, *frm++);
        }
        crc_fail = (crc == 0)? 0: 1;
    #endif
    radiostatus.rxframe = usr_radio_receive_frame(len, radiostatus.rxframe,
                                                  lqi, ed, crc_fail);
}
Exemple #4
0
/**
 * @brief Start CCA.
 *
 * @param parameter Pointer to trx_id
 */
static void cca_start(void *parameter)
{
	trx_id_t trx_id = *(trx_id_t *)parameter;

	/* Check if trx is currently detecting a frame ota */
	if (trx_state[trx_id] == RF_RX) {
		uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id;
		uint8_t agc_freeze
			= trx_bit_read(reg_offset + SR_RF09_AGCC_FRZS);
		if (agc_freeze) {
			csma_continue(trx_id);
		} else {
#ifdef SUPPORT_MODE_SWITCH
			if (tal_pib[trx_id].ModeSwitchEnabled) {
				trigger_cca_meaurement(trx_id);
			} else
#endif
			{
				transmit_frame(trx_id, WITH_CCA);
			}
		}
	} else {
#ifdef SUPPORT_MODE_SWITCH
		if (tal_pib[trx_id].ModeSwitchEnabled) {
			trigger_cca_meaurement(trx_id);
		} else
#endif
		{
			transmit_frame(trx_id, WITH_CCA);
		}
	}
}
Exemple #5
0
void radio_init(uint8_t * rxbuf, uint8_t rxbufsz)
{
trx_regval_t status;
    /* init cpu peripherals and global IRQ enable */
    radiostatus.rxframe = rxbuf;
    radiostatus.rxframesz = rxbufsz;
    //trx_set_irq_handler(radio_irq_handler);
    /* transceiver initialization */

    TRX_RESET_LOW();
    TRX_SLPTR_LOW();
    DELAY_US(TRX_RESET_TIME_US);
    #if defined(CUSTOM_RESET_TIME_MS)
        DELAY_MS(CUSTOM_RESET_TIME_MS);
    #endif
    TRX_RESET_HIGH();

    /* disable IRQ and clear any pending IRQs */
    trx_reg_write(RG_IRQ_MASK, 0);
    trx_reg_read(RG_IRQ_STATUS);
    trx_bit_write(SR_TRX_CMD, CMD_TRX_OFF);
    DELAY_US(510);
    status = trx_bit_read(SR_TRX_STATUS);
    if (status != TRX_OFF)
    {
        radio_error(STATE_SET_FAILED);
    }
    trx_bit_write(SR_TX_AUTO_CRC_ON, 1);
    trx_reg_write(RG_IRQ_MASK, TRX_IRQ_RX_START | TRX_IRQ_RX_END | TRX_IRQ_TX_END);

    radiostatus.state = STATE_OFF;
    radiostatus.idle_state = STATE_OFF;
}
/**
 * \brief Save all user settings before Start of CW transmission
 */
void save_all_settings(void)
{
#if (ANTENNA_DIVERSITY == 1)
	tal_get_curr_trx_config(ANT_DIVERSITY, &ant_div_before_ct);

	if (ANT_DIV_DISABLE == ant_div_before_ct) {
		tal_get_curr_trx_config(ANT_CTRL, &ant_sel_before_ct);
	}

#endif

#if (TAL_TYPE == AT86RF233)
	cc_band_ct = trx_bit_read(SR_CC_BAND);
	cc_number_ct = trx_bit_read(SR_CC_NUMBER);
#endif /* End of #if(TAL_TYPE == AT86RF233) */
}
inline uint8_t trx_frame_read_data_crc(uint8_t *data, uint8_t datasz, uint8_t *lqi, bool *crc_ok)
{
    if (crc_ok != NULL)
    {
        *crc_ok = (trx_bit_read(SR_RX_CRC_VALID) == 1);
    }
    return trx_frame_read(data, datasz, lqi);
}
Exemple #8
0
/*
 * \brief Perform a CCA
 *
 * This function performs a CCA request.
 *
 * \return phy_enum_t PHY_IDLE or PHY_BUSY
 */
phy_enum_t tfa_cca_perform(void)
{
	tal_trx_status_t trx_status;
	uint8_t cca_status;
	uint8_t cca_done;

	/* Ensure that trx is not in SLEEP for register access */
	do {
		trx_status = set_trx_state(CMD_TRX_OFF);
	} while (trx_status != TRX_OFF);

	/* no interest in receiving frames while doing CCA */
	trx_bit_write(SR_RX_PDT_DIS, RX_DISABLE); /* disable frame reception
	                                           * indication */

	/* Set trx to rx mode. */
	do {
		trx_status = set_trx_state(CMD_RX_ON);
	} while (trx_status != RX_ON);

	/* Start CCA */
	trx_bit_write(SR_CCA_REQUEST, CCA_START);

	/* wait until CCA is done */
	pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(CCA_DURATION_SYM));
	do {
		/* poll until CCA is really done */
		cca_done = trx_bit_read(SR_CCA_DONE);
	} while (cca_done != CCA_DETECTION_DONE);

	set_trx_state(CMD_TRX_OFF);

	/* Check if channel was idle or busy. */
	if (trx_bit_read(SR_CCA_STATUS) == CCA_STATUS_CHANNEL_IS_IDLE) {
		cca_status = PHY_IDLE;
	} else {
		cca_status = PHY_BUSY;
	}

	/* Enable frame reception again. */
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);

	return (phy_enum_t)cca_status;
}
Exemple #9
0
/**
 * \brief Switches the PLL on
 * \ingroup group_tal_state_machine
 */
static void switch_pll_on(void)
{
	uint32_t start_time;
	uint32_t current_time;

	/* Check if trx is in TRX_OFF; only from PLL_ON the following procedure
	 * is applicable */
	if (trx_bit_read(SR_TRX_STATUS) != TRX_OFF) {
		Assert(
				"Switch PLL_ON failed, because trx is not in TRX_OFF" ==
				0);
		return;
	}

	/* Clear all pending trx interrupts */
	trx_reg_read(RG_IRQ_STATUS);
	/* Get current IRQ mask */
	uint8_t trx_irq_mask = trx_reg_read(RG_IRQ_MASK);
	/* Enable transceiver's PLL lock interrupt */
	trx_reg_write(RG_IRQ_MASK, TRX_IRQ_0_PLL_LOCK);
	ENTER_TRX_REGION(); /* Disable trx interrupt handling */

	/* Switch PLL on */
	trx_reg_write(RG_TRX_STATE, CMD_PLL_ON);
	pal_get_current_time(&start_time);

	/* Wait for transceiver interrupt: check for IRQ line */
	while (TRX_IRQ_HIGH() == false) {
		/* Handle errata "potential long PLL settling duration". */
		pal_get_current_time(&current_time);
		if (pal_sub_time_us(current_time,
				start_time) > PLL_LOCK_DURATION_MAX_US) {
			uint8_t reg_value;

			reg_value = trx_reg_read(RG_PLL_CF);
			if (reg_value & 0x01) {
				reg_value &= 0xFE;
			} else {
				reg_value |= 0x01;
			}

			trx_reg_write(RG_PLL_CF, reg_value);
			pal_get_current_time(&start_time);
		}

		/* Wait until trx line has been raised. */
	}

	/* Clear PLL lock interrupt at trx */
	trx_reg_read(RG_IRQ_STATUS);
	/* Clear MCU's interrupt flag */
	pal_trx_irq_flag_clr();
	LEAVE_TRX_REGION(); /* Enable trx interrupt handling again */
	/* Restore transceiver's interrupt mask. */
	trx_reg_write(RG_IRQ_MASK, trx_irq_mask);
}
void radio_init(uint8_t * rxbuf, uint8_t rxbufsz)
{
trx_regval_t status;
    /* init cpu peripherals and global IRQ enable */
    radiostatus.rxframe = rxbuf;
    radiostatus.rxframesz = rxbufsz;
    trx_io_init(DEFAULT_SPI_RATE);
    trx_set_irq_handler(radio_irq_handler);
    /* transceiver initialization */

    TRX_RESET_LOW();
    TRX_SLPTR_LOW();
    DELAY_US(TRX_RESET_TIME_US);
    #if defined(CUSTOM_RESET_TIME_MS)
        DELAY_MS(CUSTOM_RESET_TIME_MS);
    #endif
    TRX_RESET_HIGH();

    /* disable IRQ and clear any pending IRQs */
    trx_reg_write(RG_IRQ_MASK, 0);
    trx_reg_read(RG_IRQ_STATUS);

#if RADIO_TYPE == RADIO_AT86RF212
	trx_reg_write(RG_TRX_CTRL_0, 0x19);
#ifdef CHINABAND
	trx_reg_write(RG_CC_CTRL_1, CCBAND );
	trx_reg_write(RG_CC_CTRL_0, CCNUMBER);//channel 0
	trx_reg_write(RG_TRX_CTRL_2, TRX_OQPSK250);
	/*trx_bit_write(SR_OQPSK_SUB1_RC_EN,1);
	trx_bit_write(SR_BPSK_OQPSK,1);
	trx_bit_write(SR_SUB_MODE,1);
	trx_bit_write(SR_OQPSK_DATA_RATE,0);
	trx_bit_write(SR_CC_BAND,CCBAND);
	*/
	DELAY_US(510);
#endif
	trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
	DELAY_US(510);
#else
    trx_bit_write(SR_TRX_CMD, CMD_TRX_OFF);
    DELAY_US(510);
#endif    
    do
    {    
        status = trx_bit_read(SR_TRX_STATUS);
    }
    while (status != TRX_OFF);

    trx_bit_write(SR_TX_AUTO_CRC_ON, 1);
    trx_reg_write(RG_IRQ_MASK, TRX_IRQ_RX_START | TRX_IRQ_TRX_END);

    radiostatus.state = STATE_OFF;
    radiostatus.idle_state = STATE_OFF;
}
Exemple #11
0
/**
 * @brief Frame reception
 *
 */
void radio_receive_frame(void)
{
    uint8_t len, lqi, crc_fail;
    
    crc_fail = trx_bit_read(SR_RX_CRC_VALID) ? 0 : 1;
    len = trx_frame_read(radiostatus.rxframe, radiostatus.rxframesz, &lqi);
    len &= ~0x80;
	
    radiostatus.rxframe = usr_radio_receive_frame(len, radiostatus.rxframe,
                                                  lqi, crc_fail);
}
/**
 * @brief IRQ handler for radio functions.
 *
 * This function is called in the transceiver interrupt routine.
 * Keep the implementation of the callback functions
 * (usr_radio_irq, usr_radio_receive_frame) short and efficient.
 *
 * @parm cause  value of the interrupt status register
 *
 */
void radio_irq_handler(uint8_t cause)
{
    if (cause & TRX_IRQ_TRX_END)
    {
        if (STATE_RX == radiostatus.state ||
            STATE_RXAUTO == radiostatus.state)
        {
            radio_receive_frame();
        }
        else if (STATE_TX == radiostatus.state)
        {
            #ifdef TRX_TX_PA_EI
                TRX_TX_PA_DI();
            #endif
            usr_radio_tx_done(TX_OK);
            radio_set_state(radiostatus.idle_state);
        }
        else if (STATE_TXAUTO == radiostatus.state)
        {
            #ifdef TRX_TX_PA_EI
                TRX_TX_PA_DI();
            #endif
            uint8_t trac_status = trx_bit_read(SR_TRAC_STATUS);
            uint8_t result;
            switch (trac_status)
            {
            case TRAC_SUCCESS:
#if defined TRAC_SUCCESS_DATA_PENDING
            case TRAC_SUCCESS_DATA_PENDING:
#endif
#if defined TRAC_SUCCESS_WAIT_FOR_ACK
            case TRAC_SUCCESS_WAIT_FOR_ACK:
#endif
                result = TX_OK;
                break;

            case TRAC_CHANNEL_ACCESS_FAILURE:
                result = TX_CCA_FAIL;
                break;

            case TRAC_NO_ACK:
                result = TX_NO_ACK;
                break;

            default:
                result = TX_FAIL;
            }
            usr_radio_tx_done(result);
            radio_set_state(radiostatus.idle_state);
        }
    }
    usr_radio_irq(cause);
}
Exemple #13
0
/**
 * @brief Handle received frame interrupt
 *
 * This function handles transceiver interrupts for received frames.
 *
 * @param trx_id Transceiver identifier
 */
void handle_rx_end_irq(trx_id_t trx_id)
{
	trx_state[trx_id] = RF_TXPREP;
  #if (defined RF215V1) && ((defined SUPPORT_FSK) || (defined SUPPORT_OQPSK))
	stop_rpc(trx_id);
  #endif

	if (upload_frame(trx_id) == false) {
		return;
	}

#ifdef RX_WHILE_BACKOFF
	if (tx_state[trx_id] == TX_BACKOFF) {
		/* Stop backoff timer */
		stop_tal_timer(trx_id);
		tx_state[trx_id] = TX_DEFER;
		tal_pib[trx_id].NumRxFramesDuringBackoff++;
	}

#endif

#ifdef SUPPORT_MODE_SWITCH
	if (tal_pib[trx_id].ModeSwitchEnabled) {
		if (tal_pib[trx_id].phy.modulation == FSK) {
			uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id;
			if (trx_bit_read(reg_offset + SR_BBC0_FSKPHRRX_MS) ==
					0x01) {
				handle_rx_ms_packet(trx_id);
				return;
			}
		}

		if (tal_state[trx_id] == TAL_NEW_MODE_RECEIVING) {
			/* Restore previous PHY, i.e. CSM */
			/* Stop timer waiting for incoming frame at new mode */
			stop_tal_timer(trx_id);
			set_csm(trx_id);
			tal_state[trx_id] = TAL_IDLE;
		}
	}

#endif

#ifdef PROMISCUOUS_MODE
	if (tal_pib[trx_id].PromiscuousMode) {
		complete_rx_transaction(trx_id);
		return;
	}

#endif /* #ifdef PROMISCUOUS_MODE */

	handle_incoming_frame(trx_id);
}
Exemple #14
0
/*
 * \brief Generates a 16-bit random number used as initial seed for srand()
 *
 * This function generates a 16-bit random number by means of using the
 * Random Number Generator from the transceiver.
 * The Random Number Generator generates 2-bit random values. These 2-bit
 * random values are concatenated to the required 16-bit random seed.
 *
 * The generated random 16-bit number is feed into function srand()
 * as initial seed.
 *
 * The transceiver state is initally set to RX_ON.
 * After the completion of the random seed generation, the
 * trancseiver is set to TRX_OFF.
 *
 * As a prerequisite the preamble detector must not be disabled.
 *
 * Also in case the function is called from a different state than TRX_OFF,
 * additional trx state handling is required, such as reading the original
 * value and restoring this state after finishing the sequence.
 * Since in our case the function is called from TRX_OFF, this is not required
 * here.
 */
void tal_generate_rand_seed(void)
{
	uint16_t seed = 0;
	uint8_t cur_random_val = 0;

	/* RPC could influence the randomness; therefore disable it here. */
	uint8_t previous_RPC_value = trx_reg_read(RG_TRX_RPC);
	trx_reg_write(RG_TRX_RPC, 0xC1);

	/*
	 * We need to disable TRX IRQs while generating random values in RX_ON,
	 * we do not want to receive frames at this point of time at all.
	 */
	ENTER_TRX_REGION();

	/* Ensure that PLL has locked and receive mode is reached. */
	tal_trx_status_t trx_state;
	do {
		trx_state = set_trx_state(CMD_RX_ON);
	} while (trx_state != RX_ON);

	/* Ensure that register bit RX_PDT_DIS is set to 0. */
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);

	/*
	 * The 16-bit random value is generated from various 2-bit random
	 * values.
	 */
	for (uint8_t i = 0; i < 8; i++) {
		/* Now we can safely read the 2-bit random number. */
		cur_random_val = trx_bit_read(SR_RND_VALUE);
		seed = seed << 2;
		seed |= cur_random_val;
		PAL_WAIT_1_US(); /* wait that the random value gets updated */
	}

	set_trx_state(CMD_FORCE_TRX_OFF);

	/*
	 * Now we need to clear potential pending TRX IRQs and
	 * enable the TRX IRQs again.
	 */
	trx_reg_read(RG_IRQ_STATUS);
	pal_trx_irq_flag_clr();
	LEAVE_TRX_REGION();

	/* Set the seed for the random number generator. */
	srand(seed);

	/* Restore RPC settings. */
	trx_reg_write(RG_TRX_RPC, previous_RPC_value);
}
Exemple #15
0
/**
 * @brief Frame reception
 *
 */
void radio_receive_frame(void)
{

uint8_t len, lqi, crc_fail;
int8_t ed;

    /* @todo add RSSI_BASE_VALUE to get a dBm value */
    ed = (int8_t)trx_reg_read(RG_PHY_ED_LEVEL);
    crc_fail = trx_bit_read(SR_RX_CRC_VALID) ? 0 : 1;
    len = trx_frame_read(radiostatus.rxframe, radiostatus.rxframesz, &lqi);
    len &= ~0x80;
    radiostatus.rxframe = usr_radio_receive_frame(len, radiostatus.rxframe,
                                                  lqi, ed, crc_fail);
}
int main(void)
{
trx_regval_t rval;

    /* This will stop the application before initializing the radio transceiver
     * (ISP issue with MISO pin, see FAQ)
     */
    trap_if_key_pressed();

    /* Step 0: init MCU peripherals */
    LED_INIT();
    trx_io_init(SPI_RATE_1_2);
    LED_SET_VALUE(LED_MAX_VALUE);
    LED_SET_VALUE(0);

    /* Step 1: initialize the transceiver */
    TRX_RESET_LOW();
    TRX_SLPTR_LOW();
    DELAY_US(TRX_RESET_TIME_US);
    TRX_RESET_HIGH();
    trx_reg_write(RG_TRX_STATE,CMD_TRX_OFF);
    DELAY_US(TRX_INIT_TIME_US);
    rval = trx_bit_read(SR_TRX_STATUS);
    ERR_CHECK(TRX_OFF!=rval);
    LED_SET_VALUE(1);

    /* Step 2: setup transmitter
     * - configure radio channel
     * - go into RX state,
     * - enable "receive end" IRQ
     */
    trx_bit_write(SR_CHANNEL,CHANNEL);
    trx_reg_write(RG_TRX_STATE,CMD_RX_ON);
#if defined(TRX_IRQ_TRX_END)
    trx_reg_write(RG_IRQ_MASK,TRX_IRQ_TRX_END);
#elif defined(TRX_IRQ_RX_END)
    trx_reg_write(RG_IRQ_MASK,TRX_IRQ_RX_END);
#else
#  error "Unknown IRQ bits"
#endif
    sei();
    LED_SET_VALUE(2);

    /* Step 3: Going to receive frames */
    rxcnt = 0;

    LED_SET_VALUE(0);
    while(1);
}
/*
 * \brief handle the tx power settings in case of External PA enabled,
 * and the channel changes from or to 26.This is to meet the FCC compliance
 *
 * \param Current channel and Previous channel
 */
void limit_tx_power_in_ch26(uint8_t curr_chnl, uint8_t prev_chnl)
{
	pib_value_t pib_value;

	/* If the cuurent channel set to 26*/
	if (curr_chnl == CHANNEL_26) {
		/* Get last previous non 26 channel tx power  */
		if (prev_chnl != CHANNEL_26) {
			tal_pib_get(phyTransmitPower, &prev_non_26chn_tx_power);
		}

		/* If the Tx power is more than 13dBm, i.e. TX_PWR < 0x0d */
		if (trx_bit_read(SR_TX_PWR) <= MAX_TX_PWR_REG_VAL_CH26) {
			pib_value.pib_value_8bit = DEFAULT_TX_POWER_CH26;
			tal_pib_set(phyTransmitPower, &pib_value);
			curr_trx_config_params.tx_power_reg = trx_bit_read(
					SR_TX_PWR);
			curr_trx_config_params.tx_power_dbm
				= CONV_phyTransmitPower_TO_DBM(
					pib_value.pib_value_8bit);
		}
	} else {
		/* if the channel changed from 26 to other  */
		if (prev_chnl == CHANNEL_26) {
			/* Set back the tx power to default value i.e. 20dBm,
			 *TX_PWR 0x09 */
			pib_value.pib_value_8bit = prev_non_26chn_tx_power;
			tal_pib_set(phyTransmitPower, &pib_value);
			curr_trx_config_params.tx_power_reg = trx_bit_read(
					SR_TX_PWR);
			curr_trx_config_params.tx_power_dbm
				= CONV_phyTransmitPower_TO_DBM(
					pib_value.pib_value_8bit);
		}
	}
}
Exemple #18
0
/*
 * \brief handling of CCA result.
 */
void cca_done_handling(void)
{
	set_trx_state(CMD_PLL_ON); /* leave RX_ON */
	/* Restore IRQ handling */
	trx_irq_init((FUNC_PTR)trx_irq_handler_cb);
	trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE); /* Enable frame reception.
	                                         **/

	/* Check if channel was idle or busy */
	if (trx_bit_read(SR_CCA_STATUS) == CCA_STATUS_CHANNEL_IS_IDLE) {
		tx_frame();
	} else {
		tal_state = TAL_CSMA_CONTINUE;
	}
}
radio_cca_t radio_do_cca(void)
{
uint8_t tmp, trxcmd, trxstatus;
radio_cca_t ret = RADIO_CCA_FREE;

    trxcmd = trx_reg_read(RG_TRX_STATE);
    trx_reg_write(RG_TRX_STATE, CMD_RX_ON);
    tmp = 130;
    do
    {
         trxstatus = trx_bit_read(SR_TRX_STATUS);
         if ((RX_ON == trxstatus) || (BUSY_RX == trxstatus))
         {
            break;
         }
         DELAY_US(32); /* wait for one octett */
    }
    while(--tmp);

    trx_reg_write(RG_TRX_STATE, CMD_PLL_ON);
    trx_reg_write(RG_TRX_STATE, CMD_RX_ON);

    trx_bit_write(SR_CCA_REQUEST,1);
    DELAY_US(140);
    /* we need to read the whole status register
     * because CCA_DONE and CCA_STATUS are valid
     * only for one read, after the read they are reset
     */
    tmp = trx_reg_read(RG_TRX_STATUS);

    if(0 == (tmp & 0x80))
    {
        ret = RADIO_CCA_FAIL;
    }
    else if (tmp & 0x40)
    {
        ret = RADIO_CCA_FREE;
    }
    else
    {
        ret = RADIO_CCA_BUSY;
    }

    trx_reg_write(RG_TRX_STATE, trxcmd);

    return ret;
}
Exemple #20
0
/**
 * \brief Initializes the transceiver
 *
 * This function is called to initialize the transceiver.
 *
 * \return MAC_SUCCESS  if the transceiver state is changed to TRX_OFF and the
 *                 current device part number and version number are correct;
 *         FAILURE otherwise
 */
static retval_t trx_init(void)
{
	tal_trx_status_t trx_status;
	uint8_t poll_counter = 0;

	sysclk_enable_peripheral_clock(&TRX_CTRL_0);
	TRX_RST_HIGH();
	TRX_SLP_TR_LOW();

	pal_timer_delay(P_ON_TO_CLKM_AVAILABLE_TYP_US);

	/* Apply reset pulse */
	TRX_RST_LOW();
	pal_timer_delay(RST_PULSE_WIDTH_US);
	TRX_RST_HIGH();

	/* Verify that the trx has reached TRX_OFF. */
	poll_counter = 0;
	do {
		/* Wait a short time interval. */
		pal_timer_delay(TRX_POLL_WAIT_TIME_US);

		trx_status = (tal_trx_status_t)trx_bit_read(SR_TRX_STATUS);

		/* Wait not more than max. value of TR2. */
		if (poll_counter == RESET_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;

#if !defined(FPGA_EMULATION)
	/* Check if actually running on an ATmegaRFR2 device. */
	if (ATMEGARFR2_PART_NUM != trx_reg_read(RG_PART_NUM)) {
		return FAILURE;
	}
#endif
	return MAC_SUCCESS;
}
Exemple #21
0
retval_t  tal_ext_pa_ctrl(bool pa_ext_sw_ctrl)
{
	bool temp;
	trx_bit_write(SR_PA_EXT_EN, pa_ext_sw_ctrl);
#if (TAL_TYPE == ATMEGARFA1)
	CONF_REG_WRITE();
#endif /* TAL_TYPE == ATMEGA128RFA1 */
	/* Read the PA_EXT_EN bit to check the configuration */
	temp = /*(bool)*/ trx_bit_read(SR_PA_EXT_EN);
	if (pa_ext_sw_ctrl == temp) {
		/* return success if the configuration is done correctly */
		return MAC_SUCCESS;
	} else {
		/* return success if the configuration is not done correctly */
		return FAILURE;
	}
}
Exemple #22
0
/**
 * @brief Handles incoming frame from transceiver
 *
 * @param trx_id Transceiver identifier
 */
static void handle_incoming_frame(trx_id_t trx_id)
{
	uint16_t reg_offset = RF_BASE_ADDR_OFFSET * trx_id;

	if (is_frame_an_ack(trx_id)) {
		if (tx_state[trx_id] == TX_WAITING_FOR_ACK) {
			if (is_ack_valid(trx_id)) {
				/* Stop ACK timeout timer */
				stop_tal_timer(trx_id);
				/* Re-store frame filter to pass "normal" frames
				 **/
				/* Configure frame filter to receive all allowed
				 *frame types */
#ifdef SUPPORT_FRAME_FILTER_CONFIGURATION
				trx_reg_write(reg_offset + RG_BBC0_AFFTM,
						tal_pib[trx_id].frame_types);
#else
				trx_reg_write(reg_offset + RG_BBC0_AFFTM,
						DEFAULT_FRAME_TYPES);
#endif
				tx_done_handling(trx_id, MAC_SUCCESS);
			} else {
				/* Continue waiting for incoming ACK */
				switch_to_rx(trx_id);
			}
		} else {
			/* No interest in ACKs */
			switch_to_rx(trx_id);
		}

		return; /* no further processing of ACK frames */
	}

	/* Check if ACK transmission is done by transceiver */
	bool ack_transmitting = trx_bit_read(reg_offset + SR_BBC0_AMCS_AACKFT);
	if (ack_transmitting) {
	} else {
		complete_rx_transaction(trx_id);
#ifdef RX_WHILE_BACKOFF
		if (tx_state[trx_id] == TX_DEFER) {
			csma_start(trx_id);
		}

#endif
	}
}
/**
 * \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 */
	TRX_SLP_TR_LOW();
	pal_timer_delay(SLEEP_TO_TRX_OFF_TYP_US);

	/* Apply reset pulse */
	TRX_RST_LOW();
	pal_timer_delay(RST_PULSE_WIDTH_US);
	TRX_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)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;
}
Exemple #24
0
/**
 * \brief      Transmit a frame already put in the radio with 'prepare'
 * \param payload_len    Length of the frame to send
 * \return     Returns success/fail, refer to radio.h for explanation
 */
int rf233_transmit() {
  static uint8_t status_now;

  status_now = rf233_status();
  PRINTF("RF233: attempting transmit, in state %s\n", state_str(status_now));

  if (status_now == STATE_BUSY_RX_AACK ||
      status_now == STATE_BUSY_TX_ARET) {
    PRINTF("RF233: collision, was in state %s\n", state_str(status_now));
    /* NOTE: to avoid loops */
    return RADIO_TX_ERR;;
  }
  
  if (status_now != STATE_PLL_ON) {
    trx_reg_write(RF233_REG_TRX_STATE, STATE_PLL_ON);
    do { // I think this code is broken, does nothing -pal
      status_now = trx_bit_read(RF233_REG_TRX_STATUS, 0x1F, 0);
    } while (status_now == 0x1f);
  }
  
  if (rf233_status() != STATE_PLL_ON) {
    /* failed moving into PLL_ON state, gracefully try to recover */
    PRINTF("RF233: failed going to STATE_PLL_ON\n");
    RF233_COMMAND(TRXCMD_PLL_ON);   /* try again */
    static uint8_t state;
    state = rf233_status();
    if(state != STATE_PLL_ON) {
      PRINTF("RF233: graceful recovery (in tx) failed, giving up. State: 0x%02X\n", rf233_status());
      return RADIO_TX_ERR;
    }
  }
  
  /* perform transmission */
  flag_transmit = 1;
  radio_tx = false;
  RF233_COMMAND(TRXCMD_TX_ARET_ON);
  RF233_COMMAND(TRXCMD_TX_START);

  PRINTF("RF233:: Issued TX_START, wait for completion interrupt.\n");
  wait_for(&radio_tx);
  PRINTF("RF233: tx ok\n\n");
  
  return RADIO_TX_OK;
}
Exemple #25
0
/*
 * \brief Generates a 16-bit random number used as initial seed for srand()
 *
 * This function generates a 16-bit random number by means of using the
 * Random Number Generator from the transceiver.
 * The Random Number Generator generates 2-bit random values. These 2-bit
 * random values are concatenated to the required 16-bit random seed.
 *
 * The generated random 16-bit number is feed into function srand()
 * as initial seed.
 *
 * The transceiver state is initally set to RX_ON.
 * After the completion of the random seed generation, the
 * trancseiver is set to TRX_OFF.
 *
 * As a prerequisite the preamble detector must not be disabled.
 *
 * Also in case the function is called from a different state than TRX_OFF,
 * additional trx state handling is required, such as reading the original
 * value and restoring this state after finishing the sequence.
 * Since in our case the function is called from TRX_OFF, this is not required
 * here.
 */
void tal_generate_rand_seed(void)
{
	uint16_t seed = 0;
	uint8_t cur_random_val = 0;

	/* Ensure that PLL has locked and receive mode is reached. */
	tal_trx_status_t trx_state;
	do {
		trx_state = set_trx_state(CMD_RX_ON);
	} while (trx_state != RX_ON);

	/* Ensure that register bit RX_PDT_DIS is set to 0. */
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);

	/*
	 * We need to disable TRX IRQs while generating random values in RX_ON,
	 * we do not want to receive frames at this point of time at all.
	 */
	trx_reg_write(RG_IRQ_MASK, TRX_IRQ_NONE);

	/*
	 * The 16-bit random value is generated from various 2-bit random
	 * values.
	 */
	for (uint8_t i = 0; i < 8; i++) {
		/* Now we can safely read the 2-bit random number. */
		cur_random_val = trx_bit_read(SR_RND_VALUE);
		seed = seed << 2;
		seed |= cur_random_val;
		PAL_WAIT_1_US(); /* wait that the random value gets updated */
	}

	set_trx_state(CMD_FORCE_TRX_OFF);

	/*
	 * Now we need to clear potential pending TRX IRQs and
	 * enable the TRX IRQs again.
	 */
	trx_reg_write(RG_IRQ_STATUS, 0xFF);
	trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);

	/* Set the seed for the random number generator. */
	srand(seed);
}
Exemple #26
0
retval_t tal_set_tx_pwr(bool type, int8_t pwr_value)
{
	uint64_t temp_var;
	int8_t tx_pwr_dbm = 0;
	/* modify the register for tx_pwr and set the tal_pib accordingly */
	if (true == type) {
		if (MAC_SUCCESS ==
				tal_convert_reg_value_to_dBm(pwr_value,
				&tx_pwr_dbm)) {
			temp_var = CONV_DBM_TO_phyTransmitPower(tx_pwr_dbm);
			tal_pib_set(phyTransmitPower, (pib_value_t *)&temp_var);

			/* To make sure that TX_PWR register is updated with the
			 * value whatever user povided.Otherwise lowest dBm
			 * power
			 * (highest reg value will be taken)
			 */
			trx_bit_write(SR_TX_PWR, pwr_value);
#if (TAL_TYPE == ATMEGARFA1)
			CONF_REG_WRITE();
#endif /* TAL_TYPE == ATMEGA128RFA1 */
			return MAC_SUCCESS;
		} else {
			/* return invalid parameter if out of range */
			return MAC_INVALID_PARAMETER;
		}
	} else {
		temp_var = CONV_DBM_TO_phyTransmitPower(pwr_value);
		tal_pib_set(phyTransmitPower, (pib_value_t *)&temp_var);
	}

	uint8_t reg_value = convert_phyTransmitPower_to_reg_value(
			tal_pib.TransmitPower);
	/* check the value written in the transceiver register */
	uint8_t temp = trx_bit_read(SR_TX_PWR);
	if (temp == reg_value) {
		return MAC_SUCCESS;
	} else {
		return FAILURE;
	}
}
Exemple #27
0
/**
 * \brief Performs CCA twice
 */
static uint8_t perform_cca_twice(void)
{
	uint8_t cca_status;
	uint8_t cca_done;
	uint8_t CW = 2;
	uint32_t now_time_us;

	do {
		pal_get_current_time(&now_time_us);
	} while (pal_add_time_us(now_time_us,
			(SLEEP_TO_TRX_OFF_TYP_US +
			CCA_PREPARATION_DURATION_US)) <
			cca_starttime_us);

#if ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT))
	if (tal_beacon_transmission) {
#if (_DEBUG_ > 0)
		Assert("Ongoing beacon transmission, slotted CSMA busy" == 0);
#endif
		return PHY_BUSY;
	}

#endif /* ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT)) */

	/* Ensure that trx is at least in TRX_OFF mode at this time. */
	if (tal_trx_status == TRX_SLEEP) {
		set_trx_state(CMD_TRX_OFF);
	}

	do {
		pal_get_current_time(&now_time_us);
	} while (pal_add_time_us(now_time_us,
			(TRX_OFF_TO_PLL_ON_TIME_US +
			CCA_PREPARATION_DURATION_US)) <
			cca_starttime_us);

	/*
	 * Set trx to PLL_ON.
	 * If trx is busy and trx cannot be set to PLL_ON, assess channel as
	 * busy.
	 */
	if (set_trx_state(CMD_PLL_ON) != PLL_ON) {
		return PHY_BUSY;
	}

	/* no interest in receiving frames while doing CCA */
	trx_bit_write(SR_RX_PDT_DIS, RX_DISABLE); /* disable frame reception
	                                           * indication */

	/* do CCA twice */
	do {
		/* wait here until 16us before backoff boundary */
		/* assume TRX is in PLL_ON */
		do {
			pal_get_current_time(&now_time_us);
		} while (pal_add_time_us(now_time_us,
				CCA_PRE_START_DURATION_US) <
				cca_starttime_us);

		set_trx_state(CMD_RX_ON);

		/* debug pin to switch on: define ENABLE_DEBUG_PINS,
		 * pal_config.h */
		PIN_CCA_START();

		/* Start CCA */
		trx_bit_write(SR_CCA_REQUEST, CCA_START);

		/* wait until CCA is done and get status */
		pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(CCA_DURATION_SYM));

		do {
			/* poll until CCA is really done; */
			cca_done = trx_bit_read(SR_CCA_DONE);
		} while (cca_done != CCA_COMPLETED);

		/* between both CCA switch trx to PLL_ON to reduce power
		 * consumption */
		set_trx_state(CMD_PLL_ON);

		/* debug pin to switch on: define ENABLE_DEBUG_PINS,
		 * pal_config.h */
		PIN_CCA_END();

		/* check if channel was idle or busy */
		if (trx_bit_read(SR_CCA_STATUS) == CCA_CH_IDLE) {
			/* do next CCA at next backoff boundary */
			cca_starttime_us = pal_add_time_us(cca_starttime_us,
					TAL_CONVERT_SYMBOLS_TO_US(
					aUnitBackoffPeriod));
			CW--;
			cca_status = PHY_IDLE;
		} else { /* PHY busy */
			cca_status = PHY_BUSY;
			set_trx_state(CMD_RX_AACK_ON);
			break; /* if channel is busy do no do CCA for the second
			        * time */
		}
	} while (CW > 0);

	/*
	 * Keep trx ready for transmission if channel is idle.
	 * The transceiver is still in PLL_ON.
	 * If the channel is not idle, the trx handling is done in
	 * csma_backoff().
	 */

	/*
	 * Clear CCA interrupt flag.
	 * This is only necessary for debugging, because only in debug mode
	 * interrupt that are not handled cause an assert in the ISR.
	 */
#if (_DEBUG_ > 0)
	trx_reg_read(RG_IRQ_STATUS);
#endif

	/*
	 * Since we are not interested in any frames that might be received
	 * during CCA, reject any information that indicates a previous frame
	 * reception.
	 */
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE); /* enable frame reception
	                                          * indication */

	return cca_status;
}
Exemple #28
0
/*
 * \brief Handles interrupts issued due to end of transmission
 */
void handle_tx_end_irq(void)
{
	/* Check if TX_END interrupt, is issued due to automatic ACK
	 * transmission. */
#if ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT))
	if ((tal_state != TAL_TX_AUTO) && (!tal_beacon_transmission))
#else
	if (tal_state != TAL_TX_AUTO)
#endif
	{
		/* Automatic ACK transmission completed -> No further
		 * processing. */
		return;
	}

#if ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT))
	if (tal_beacon_transmission) {
		tal_beacon_transmission = false;

		if (tal_csma_state == BACKOFF_WAITING_FOR_BEACON) {
			/* Slotted CSMA has been waiting for a beacon, now it
			 * can continue. */
			tal_csma_state = CSMA_HANDLE_BEACON;
		}
	} else
#endif /* ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT)) */
	{
		/* Read trac status before enabling RX_AACK_ON. */
		trx_trac_status = (trx_trac_status_t)trx_bit_read(
				SR_TRAC_STATUS);

#ifdef BEACON_SUPPORT
		if (tal_csma_state == FRAME_SENDING) { /* Transmission was
			                                * issued by slotted CSMA
			                                **/
			PIN_TX_END();
			tal_state = TAL_SLOTTED_CSMA;

			/* Map status message of transceiver to TAL constants.
			**/
			switch (trx_trac_status) {
			case TRAC_SUCCESS_DATA_PENDING:
				PIN_ACK_OK_START();
				tal_csma_state = TX_DONE_FRAME_PENDING;
				break;

			case TRAC_SUCCESS:
				PIN_ACK_OK_START();
				tal_csma_state = TX_DONE_SUCCESS;
				break;

			case TRAC_CHANNEL_ACCESS_FAILURE:
				PIN_NO_ACK_START();
				tal_csma_state = CSMA_ACCESS_FAILURE;
				break;

			case TRAC_NO_ACK:
				PIN_NO_ACK_START();
				tal_csma_state = TX_DONE_NO_ACK;
				break;

			case TRAC_INVALID: /* Handle this in the same way as
				            * default. */
			default:
				Assert("not handled trac status" == 0);
				tal_csma_state = CSMA_ACCESS_FAILURE;
				break;
			}
			PIN_ACK_OK_END();
			PIN_ACK_WAITING_END();
		} else
#endif  /* BEACON_SUPPORT */
		/* Trx has handled the entire transmission incl. CSMA */
		{
			tal_state = TAL_TX_DONE; /* Further handling is done by
			                          * tx_done_handling() */
		}
	}

	/*
	 * After transmission has finished, switch receiver on again.
	 * Check if receive buffer is available.
	 */
	if (NULL == tal_rx_buffer) {
		set_trx_state(CMD_PLL_ON);
		tal_rx_on_required = true;
	} else {
		set_trx_state(CMD_RX_AACK_ON);
	}
}
Exemple #29
0
/*
 * \brief Transceiver interrupt handler
 *
 * This function handles the transceiver generated interrupts.
 */
void trx_irq_handler_cb(void)
{
    trx_irq_reason_t trx_irq_cause;

    trx_irq_cause = (trx_irq_reason_t)trx_reg_read(RG_IRQ_STATUS);

#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)
#if (ANTENNA_DIVERSITY == 1) || (DISABLE_TSTAMP_IRQ == 1)
    if (trx_irq_cause & TRX_IRQ_RX_START) {
        /*
         * Get timestamp.
         *
         * In case Antenna diversity is used or the utilization of
         * the Timestamp IRQ is disabled, the timestamp needs to be read
         * now
         * the "old-fashioned" way.
         *
         * The timestamping is generally only done for
         * beaconing networks or if timestamping is explicitly enabled.
         */
        pal_trx_read_timestamp(&tal_rx_timestamp);
    }
#endif  /* #if (ANTENNA_DIVERSITY == 1) || (DISABLE_TSTAMP_IRQ == 1) */
#endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

    if (trx_irq_cause & TRX_IRQ_TRX_END) {
        /*
         * TRX_END reason depends on if the trx is currently used for
         * transmission or reception.
         */
#if ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT))
        if ((tal_state == TAL_TX_AUTO) || tal_beacon_transmission)
#else
        if (tal_state == TAL_TX_AUTO)
#endif
        {
            /* Get the result and push it to the queue. */
            if (trx_irq_cause & TRX_IRQ_TRX_UR) {
                handle_tx_end_irq(true); /* see tal_tx.c */
            } else {
                handle_tx_end_irq(false); /* see tal_tx.c */
            }
        } else { /* Other tal_state than TAL_TX_... */
            /* Handle rx interrupt. */
            handle_received_frame_irq(); /* see tal_rx.c */

#if (defined SW_CONTROLLED_CSMA) && (defined RX_WHILE_BACKOFF)
            if (tal_state == TAL_BACKOFF) {
                pal_timer_stop(TAL_T_BOFF);
                tal_state = TAL_CSMA_CONTINUE;
            }
#endif
        }
    }

#if (ANTENNA_DIVERSITY == 1)
    else if (trx_irq_cause & TRX_IRQ_RX_START) {
        /*
         * The antenna that has been selected automatically for the
         * current frame
         * reception is set for the ACK transmission too.
         */
        if (trx_bit_read(SR_ANT_SEL) == ANT_SEL_ANTENNA_0) {
            trx_bit_write(SR_ANT_CTRL, ANT_CTRL_1);
        } else { /* antenna 1 is in use */
            trx_bit_write(SR_ANT_CTRL, ANT_CTRL_2);
        }
    }
#endif
} /* trx_irq_handler_cb() */
Exemple #30
-1
/*
 * \brief Generates a 16-bit random number used as initial seed for srand()
 *
 */
static void rf_generate_random_seed(void)
{
	uint16_t seed = 0;
	uint8_t cur_random_val = 0;

	/*
	 * We need to disable TRX IRQs while generating random values in RX_ON,
	 * we do not want to receive frames at this point of time at all.
	 */
	ENTER_TRX_REGION();

	do
	{
		trx_reg_write(RF233_REG_TRX_STATE, TRXCMD_TRX_OFF);
		
	} while (TRXCMD_TRX_OFF != rf233_status());

	do
	{
		/* Ensure that PLL has locked and receive mode is reached. */
		trx_reg_write(RF233_REG_TRX_STATE, TRXCMD_PLL_ON);
		
	} while (TRXCMD_PLL_ON != rf233_status());
	do
	{
		trx_reg_write(RF233_REG_TRX_STATE, TRXCMD_RX_ON);
		
	} while (TRXCMD_RX_ON != rf233_status());

	/* Ensure that register bit RX_PDT_DIS is set to 0. */
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);

	/*
	 * The 16-bit random value is generated from various 2-bit random
	 * values.
	 */
	for (uint8_t i = 0; i < 8; i++) {
		/* Now we can safely read the 2-bit random number. */
		cur_random_val = trx_bit_read(SR_RND_VALUE);
		seed = seed << 2;
		seed |= cur_random_val;
		delay_us(1); /* wait that the random value gets updated */
	}

	do
	{
		/* Ensure that PLL has locked and receive mode is reached. */
		trx_reg_write(RF233_REG_TRX_STATE, TRXCMD_TRX_OFF);		
	} while (TRXCMD_TRX_OFF != rf233_status());
	/*
	 * Now we need to clear potential pending TRX IRQs and
	 * enable the TRX IRQs again.
	 */
	trx_reg_read(RF233_REG_IRQ_STATUS);
	trx_irq_flag_clr();
	LEAVE_TRX_REGION();

	/* Set the seed for the random number generator. */
	srand(seed);
}