Пример #1
0
/**
 * @brief Configures the transceiver
 *
 * This function is called to configure the transceiver after reset.
 */
static void trx_config(void)
{
    /* After we have initialized a proper seed for rand(),
     * the transceiver's CSMA seed can be initialized.
     * It needs to be assured that a seed for function rand()
     * had been generated before.
     */
    /*
     * Init the SEED value of the CSMA backoff algorithm.
     */
    uint16_t rand_value = (uint16_t)rand();
    pal_trx_reg_write(RG_CSMA_SEED_0, (uint8_t)rand_value);
    pal_trx_bit_write(SR_CSMA_SEED_1, (uint8_t)(rand_value >> 8));

    pal_trx_bit_write(SR_AACK_SET_PD, PD_ACK_BIT_SET_ENABLE); /* ACKs for data requests, indicate pending data */
    pal_trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE);  /* Enable buffer protection mode */
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);
    pal_trx_reg_write(0x156, 0xFF); /* RPC feature configuration. */

#if (ANTENNA_DIVERSITY == 1)
    // Use antenna diversity
    pal_trx_bit_write(SR_ANT_CTRL, ANTENNA_DEFAULT);
    pal_trx_bit_write(SR_PDT_THRES, THRES_ANT_DIV_ENABLE);
    pal_trx_bit_write(SR_ANT_DIV_EN, ANT_DIV_ENABLE);
    pal_trx_bit_write(SR_ANT_EXT_SW_EN, ANT_EXT_SW_ENABLE);
#endif

#ifdef CCA_ED_THRESHOLD
    /*
     * Set CCA ED Threshold to other value than standard register due to
     * board specific loss (see pal_config.h). */
    pal_trx_bit_write(SR_CCA_ED_THRES, CCA_ED_THRESHOLD);
#endif
}
Пример #2
0
/**
 * @brief Starts continuous transmission on current channel
 */
void tfa_continuous_tx_start(continuous_tx_mode_t tx_mode)
{
    uint8_t txcwdata[127];

    pal_trx_bit_write(SR_TX_AUTO_CRC_ON, TX_AUTO_CRC_DISABLE);
    pal_trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
    pal_trx_reg_write(0x0176, 0x0F);     /*TST_CTRL_DIGI*/
    /* Here: use 2MBPS mode for PSD measurements.
     * Omit the two following lines, if 250k mode is desired for PRBS mode. */
    pal_trx_bit_write(SR_OQPSK_DATA_RATE, ALTRATE_2MBPS);
    pal_trx_reg_write(RG_RX_CTRL, 0xA7);
    if (tx_mode == CW_MODE)
    {
        txcwdata[0] = 1;    // length
        // Step 11 - frame buffer write access
        txcwdata[1] = 0x00; // f=fch-0.5 MHz; set value to 0xFF for f=fch+0.5MHz
        pal_trx_frame_write(txcwdata, 2);
    }
    else    // PRBS mode
    {
        txcwdata[0] = 127;   // = max length
        for (uint8_t i = 1; i < 128; i++)
        {
            txcwdata[i] = (uint8_t)rand();
        }
        pal_trx_frame_write(txcwdata, 128);
    }

    pal_trx_reg_write(RG_PART_NUM, 0x54);
    pal_trx_reg_write(RG_PART_NUM, 0x46);
    set_trx_state(CMD_PLL_ON);
    PAL_SLP_TR_HIGH();
    PAL_SLP_TR_LOW();
}
Пример #3
0
/**
 * \brief Configures the transceiver
 *
 * This function is called to configure the transceiver after reset.
 */
void trx_config(void)
{
    /* Set pin driver strength */
    pal_trx_bit_write(SR_CLKM_SHA_SEL, CLKM_SHA_DISABLE);
    pal_trx_bit_write(SR_CLKM_CTRL, CLKM_1MHZ);

    /*
     * After we have initialized a proper seed for rand(),
     * the transceiver's CSMA seed can be initialized.
     * It needs to be assured that a seed for function rand()
     * had been generated before.
     */
    /*
     * Init the SEED value of the CSMA backoff algorithm.
     */
    uint16_t rand_value = (uint16_t)rand();
    pal_trx_reg_write(RG_CSMA_SEED_0, (uint8_t)rand_value);
    pal_trx_bit_write(SR_CSMA_SEED_1, (uint8_t)(rand_value >> 8));

    /*
     * Since the TAL is supporting 802.15.4-2006,
     * frames with version number 0 (compatible to 802.15.4-2003) and
     * with version number 1 (compatible to 802.15.4-2006) are acknowledged.
     */
    pal_trx_bit_write(SR_AACK_FVN_MODE, FRAME_VERSION_01);
    pal_trx_bit_write(SR_AACK_SET_PD, SET_PD); /* ACKs for data requests, indicate pending data */
    pal_trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE);    /* Enable buffer protection mode */
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);    /* The TRX_END interrupt of the transceiver is enabled. */
    pal_trx_reg_write(RG_TRX_RPC, 0xFF); /* RPC feature configuration. */

#if (ANTENNA_DIVERSITY == 1)
    /* Use antenna diversity */
    pal_trx_bit_write(SR_ANT_CTRL, ANTENNA_DEFAULT);
    pal_trx_bit_write(SR_PDT_THRES, THRES_ANT_DIV_ENABLE);
    pal_trx_bit_write(SR_ANT_DIV_EN, ANT_DIV_ENABLE);
    pal_trx_bit_write(SR_ANT_EXT_SW_EN, ANT_EXT_SW_ENABLE);
#endif  /* ANTENNA_DIVERSITY */
#if (DISABLE_TSTAMP_IRQ == 0)
#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)
    /* Enable Rx timestamping */
    pal_trx_bit_write(SR_IRQ_2_EXT_EN, RX_TIMESTAMPING_ENABLE);
    /* Enable Tx timestamping */
    pal_trx_bit_write(SR_ARET_TX_TS_EN, TX_ARET_TIMESTAMPING_ENABLE);
#endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */
#endif

#ifdef CCA_ED_THRESHOLD
    /*
     * Set CCA ED Threshold to other value than standard register due to
     * board specific loss (see pal_config.h). */
    pal_trx_bit_write(SR_CCA_ED_THRES, CCA_ED_THRESHOLD);
#endif

#ifdef EXT_RF_FRONT_END_CTRL
    /* Enable RF front end control */
    pal_trx_bit_write(SR_PA_EXT_EN, 1);
#endif
}
Пример #4
0
/*
 * \brief Starts continuous transmission on current channel
 *
 * \param tx_mode Mode of continuous transmission (CW or PRBS)
 * \param random_content Use random content if true
 *
 * The comment 'step #' refers to the step mentioned in the RF212's datasheet.
 */
void tfa_continuous_tx_start(continuous_tx_mode_t tx_mode, bool random_content)
{
    uint8_t txcwdata[128];
    uint8_t i;

    // step 3,6: Channel is assumed to be set before
    pal_trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
    // step 7: Enable continuous transmission - step #1
    pal_trx_reg_write(0x36, 0x0F);
    if (tx_mode == CW_MODE)
    {
        // step 8: Register access: CW at Fc +/- 0.1 MHz
        pal_trx_reg_write(RG_TRX_CTRL_2, 0x0A);     // 400 kbit mode, step 8
        txcwdata[0] = 1;    // length
        txcwdata[1] = 0;
        // step 9: Frame buffer access
        pal_trx_frame_write(txcwdata, 2);
    }
    else    // PRBS mode
    {
        // step 8:
        /*
         * Step 8 is not explicitly written here, because the proper
         * value is set during reset or by updating the Channel Page.
         * After finishing CW/PRBS another reset is performed with
         * parameter set_default_pib set to false, which restores the
         * original value based on the current Channel Page.
         *
         * I.e., in order to use PRBS with a specific data rate,
         * the Channel Page needs to be udpated before starting PRBS.
         */

        txcwdata[0] = 127;   // = max length
        for (i = 1; i < 128; i++)
        {
            if (random_content)
            {
                txcwdata[i] = (uint8_t)rand();
            }
            else
            {
                txcwdata[i] = 0;
            }
        }
        // step 9: Frame buffer access
        pal_trx_frame_write(txcwdata, 128);
    }
    // step 10: Enable continuous transmission - step #2
    pal_trx_reg_write(RG_PART_NUM, 0x54);
    // step 11: Enable continuous transmission - step #3
    pal_trx_reg_write(RG_PART_NUM, 0x46);
    // step 12, 13: Stwitch PLL on
    set_trx_state(CMD_PLL_ON);
    // step 14: Initiate transmission using SLP_TR line
    PAL_SLP_TR_HIGH();
    PAL_SLP_TR_LOW();
}
Пример #5
0
/**
 * @brief Switches the PLL on
 */
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 (pal_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 */
    pal_trx_reg_read(RG_IRQ_STATUS);
    /* Get current IRQ mask */
    uint8_t trx_irq_mask = pal_trx_reg_read(RG_IRQ_MASK);
    /* Enable transceiver's PLL lock interrupt */
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_0_PLL_LOCK);
    ENTER_TRX_REGION(); // Disable trx interrupt handling

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

    /* Wait for transceiver interrupt: check for IRQ line */
    while (PAL_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 = pal_trx_reg_read(RG_PLL_CF);
            if (reg_value & 0x01)
            {
                reg_value &= 0xFE;
            }
            else
            {
                reg_value |= 0x01;
            }
            pal_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 */
    pal_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. */
    pal_trx_reg_write(RG_IRQ_MASK, trx_irq_mask);
}
Пример #6
0
Файл: tal_ed.c Проект: bswe/6.1
/*
 * \brief Starts ED Scan
 *
 * This function starts an ED Scan for the scan duration specified by the
 * MAC layer.
 *
 * \param scan_duration Specifies the ED scan duration in symbols
 *
 * \return MAC_SUCCESS - ED scan duration timer started successfully
 *         TAL_BUSY - TAL is busy servicing the previous request from MAC
 *         TAL_TRX_ASLEEP - Transceiver is currently sleeping
 *         FAILURE otherwise
 */
retval_t tal_ed_start(uint8_t scan_duration)
{
    /*
     * Check if the TAL is in idle state. Only in idle state it can
     * accept and ED request from the MAC.
     */
    if (TAL_IDLE != tal_state)
    {
        if (tal_trx_status == TRX_SLEEP)
        {
            return TAL_TRX_ASLEEP;
        }
        else
        {
            Assert("TAL is TAL_BUSY" == 0);
            return TAL_BUSY;
        }
    }

    /*
     * Disable the transceiver interrupts to prevent frame reception
     * while performing ED scan.
     */
    pal_trx_irq_dis();  /* Disable transceiver main interrupt. */
    set_trx_state(CMD_FORCE_PLL_ON);
    pal_trx_reg_read(RG_IRQ_STATUS);        /* Clear existing interrupts */
    pal_trx_bit_write(SR_RX_PDT_DIS, RX_DISABLE);
    pal_trx_irq_init((FUNC_PTR)trx_ed_irq_handler_cb);
    pal_trx_bit_write(SR_IRQ_MASK, TRX_IRQ_CCA_ED_READY); /* enable interrupt */
    pal_trx_irq_en();   /* Enable main transceiver interrupt. */

    /* Make sure that receiver is switched on. */
    if (set_trx_state(CMD_RX_ON) != RX_ON)
    {
        /* Restore previous configuration */
        pal_trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);
        pal_trx_irq_init((FUNC_PTR)trx_irq_handler_cb);
        pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT); /* enable TRX_END interrupt */
        pal_trx_irq_en();   /* Enable main transceiver interrupt. */

        return FAILURE;
    }

    // write dummy value to start measurement
    pal_trx_reg_write(RG_PHY_ED_LEVEL, 0xFF);

    /* Perform ED in TAL_ED_RUNNING state. */
    tal_state = TAL_ED_RUNNING;

    max_ed_level = 0;   // reset max value

    sampler_counter = CALCULATE_SYMBOL_TIME_SCAN_DURATION(scan_duration) / ED_SAMPLE_DURATION_SYM;

    return MAC_SUCCESS;
}
/**
 * @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 = pal_trx_reg_read(RG_TRX_RPC);
    pal_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. */
    pal_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 = pal_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.
     */
    pal_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. */
    pal_trx_reg_write(RG_TRX_RPC, previous_RPC_value);
}
Пример #8
0
/**
 * @brief Write all shadow PIB variables to the transceiver
 *
 * This function writes all shadow PIB variables to the transceiver.
 * It is assumed that the radio does not sleep.
 */
void write_all_tal_pib_to_trx(void)
{
    uint8_t *ptr_to_reg;

    ptr_to_reg = (uint8_t *)&tal_pib.PANId;
    for (uint8_t i = 0; i < 2; i++)
    {
        pal_trx_reg_write((RG_PAN_ID_0 + i), *ptr_to_reg);
        ptr_to_reg++;
    }

    ptr_to_reg = (uint8_t *)&tal_pib.IeeeAddress;
    for (uint8_t i = 0; i < 8; i++)
    {
        pal_trx_reg_write((RG_IEEE_ADDR_0 + i), *ptr_to_reg);
        ptr_to_reg++;
    }

    ptr_to_reg = (uint8_t *)&tal_pib.ShortAddress;
    for (uint8_t i = 0; i < 2; i++)
    {
        pal_trx_reg_write((RG_SHORT_ADDR_0 + i), *ptr_to_reg);
        ptr_to_reg++;
    }

    /* configure TX_ARET; CSMA and CCA */
    pal_trx_bit_write(SR_CCA_MODE, tal_pib.CCAMode);
    pal_trx_bit_write(SR_MIN_BE, tal_pib.MinBE);

    pal_trx_bit_write(SR_AACK_I_AM_COORD, tal_pib.PrivatePanCoordinator);

    /* set phy parameter */
    pal_trx_bit_write(SR_MAX_BE, tal_pib.MaxBE);

#ifdef HIGH_DATA_RATE_SUPPORT
    apply_channel_page_configuration(tal_pib.CurrentPage);
#endif

    pal_trx_bit_write(SR_CHANNEL, tal_pib.CurrentChannel);
    {
        uint8_t reg_value;

        reg_value = convert_phyTransmitPower_to_reg_value(tal_pib.TransmitPower);
        pal_trx_bit_write(SR_TX_PWR, reg_value);
    }

#ifdef PROMISCUOUS_MODE
    if (tal_pib.PromiscuousMode)
    {
        set_trx_state(CMD_RX_ON);
    }
#endif
}
Пример #9
0
/**
 * \brief Switches the PLL on
 * \ingroup group_tal_state_machine_231
 */
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 (pal_trx_bit_read(SR_TRX_STATUS) != TRX_OFF) {
		Assert(
				"Switch PLL_ON failed, because trx is not in TRX_OFF" ==
				0);
		return;
	}

	pal_trx_reg_read(RG_IRQ_STATUS); /* clear PLL lock bit */
	/* Switch PLL on */
	pal_trx_reg_write(RG_TRX_STATE, CMD_PLL_ON);

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

		if (irq_status & TRX_IRQ_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);
}
Пример #10
0
Файл: tal_ed.c Проект: bswe/6.1
/*
 * \brief Scan done
 *
 * This function updates the max_ed_level and invokes the callback function
 * tal_ed_end_cb().
 *
 * \param parameter unused callback parameter
 */
void ed_scan_done(void)
{
    pal_trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);
    pal_trx_irq_init((FUNC_PTR)trx_irq_handler_cb);
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT); /* enable TRX_END interrupt */
    pal_trx_irq_en();   /* Enable transceiver main interrupt. */

    tal_state = TAL_IDLE;   // ed scan is done
    set_trx_state(CMD_RX_AACK_ON);

#ifndef TRX_REG_RAW_VALUE
    /*
     * Scale ED result.
     * Clip values to 0xFF if > -35dBm
     */
    if (max_ed_level > CLIP_VALUE_REG)
    {
        max_ed_level = 0xFF;
    }
    else
    {
        max_ed_level = (uint8_t)(((uint16_t)max_ed_level * 0xFF) / CLIP_VALUE_REG);
    }
#endif
    tal_ed_end_cb(max_ed_level);
}
Пример #11
0
trx_retval_t tal_init(void)
{
	if (trx_init() != TRX_SUCCESS) {
		return TRX_FAILURE;
	}

	/*
	 * Do the reset stuff.
	 * Generate random seed.
	 */
	if (internal_tal_reset() != TRX_SUCCESS) {
		return TRX_FAILURE;
	}

	/* Set the default CCA mode. */
	pal_trx_bit_write(SR_CCA_MODE, CCA_MODE_DEFAULT);

	/* Default configuration to perform auto CSMA-CA */
	pal_trx_reg_write(RG_CSMA_BE, ((MAXBE_DEFAULT << 4) | MINBE_DEFAULT));
	pal_trx_bit_write(SR_MAX_CSMA_RETRIES, MAX_CSMA_BACKOFFS_DEFAULT);

	/* Set the trx in promiscuous mode to receive all frame with CRC OK */
	pal_trx_bit_write(SR_AACK_PROM_MODE, PROM_MODE_ENABLE);

	/* Configuration to perform auto CRC for transmission */
	pal_trx_bit_write(SR_TX_AUTO_CRC_ON, TX_AUTO_CRC_ENABLE);

	return TRX_SUCCESS;
}
Пример #12
0
/**
 * \brief Start CCA.
 *
 * \param parameter Unused callback parameter
 */
static void cca_start(void *parameter)
{
	tal_state = TAL_CCA;

	if (set_trx_state(CMD_PLL_ON) == PLL_ON) {
		tal_trx_status_t trx_state;
		/* No interest in receiving frames while doing CCA */
		pal_trx_bit_write(SR_RX_PDT_DIS, RX_DISABLE); /* disable frame
		                                               * reception
		                                               * indication */
		do {
			trx_state = set_trx_state(CMD_RX_ON);
		} while (trx_state != RX_ON);
		/* Setup interrupt handling for CCA IRQ */
		pal_trx_irq_init((FUNC_PTR)cca_done_irq_handler);
		pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_CCA_ED_READY); /* enable
		                                                       *CCA
		                                                       *interrupt
		                                                       **/
		/* Start CCA */
		pal_trx_bit_write(SR_CCA_REQUEST, CCA_START);
	} else {
		/* Channel is busy, i.e. device is receiving */
		tal_state = TAL_CSMA_CONTINUE;
	}

	/* Keep compiler happy. */
	parameter = parameter;
}
Пример #13
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;

    PAL_RST_HIGH();
    PAL_SLP_TR_LOW();

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

    /* Apply reset pulse */
    PAL_RST_LOW();
    pal_timer_delay(RST_PULSE_WIDTH_US);
    PAL_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 (pal_trx_reg_read(RG_PART_NUM) != PART_NUM_AT86RF233);
#endif  /* !defined FPGA_EMULATION */

    /* Verify that TRX_OFF can be written */
    pal_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)pal_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)
            pal_alert();
#endif
            return FAILURE;
        }
        poll_counter++;
    }
    while (trx_status != TRX_OFF);

    tal_trx_status = TRX_OFF;

    return MAC_SUCCESS;
}
Пример #14
0
/**
 * @brief Scan done
 *
 * This function updates the max_ed_level and invokes the callback function
 * tal_ed_end_cb().
 *
 * @param parameter unused callback parameter
 */
void ed_scan_done(void)
{
    /* Restore previous configuration */
    pal_trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);

    tal_state = TAL_IDLE;   // ed scan is done
    set_trx_state(CMD_RX_AACK_ON);

#ifndef TRX_REG_RAW_VALUE
    /*
     * Scale ED result.
     * Clip values to 0xFF if > -35dBm
     */
    if (max_ed_level > CLIP_VALUE_REG)
    {
        max_ed_level = 0xFF;
    }
    else
    {
        max_ed_level = (uint8_t)(((uint16_t)max_ed_level * 0xFF) / CLIP_VALUE_REG);
    }
#endif
    tal_ed_end_cb(max_ed_level);
}
Пример #15
0
/**
 * @brief ED Scan Interrupt
 *
 * This function handles an ED done interrupt from the transceiver.
 */
static void trx_ed_irq_handler_cb(void)
{
    uint8_t ed_value;

    /* Read the ED Value. */
    ed_value = pal_trx_reg_read(RG_PHY_ED_LEVEL);

    /*
     * Update the peak ED value received, if greater than the previously
     * read ED value.
     */
    if (ed_value > max_ed_level)
    {
        max_ed_level = ed_value;
    }

    /* Start next ED sampling */
    sampler_counter--;
    if (sampler_counter > 0)
    {
        // write dummy value to start measurement
        pal_trx_reg_write(RG_PHY_ED_LEVEL, 0xFF);
    }
    else
    {
        tal_state = TAL_ED_DONE;
    }
}
Пример #16
0
/**
 * @brief Starts ED Scan
 *
 * This function starts an ED Scan for the scan duration specified by the
 * MAC layer.
 *
 * @param scan_duration Specifies the ED scan duration in symbols
 *
 * @return MAC_SUCCESS - ED scan duration timer started successfully
 *         TAL_BUSY - TAL is busy servicing the previous request from MAC
 *         TAL_TRX_ASLEEP - Transceiver is currently sleeping
 *         FAILURE otherwise
 */
retval_t tal_ed_start(uint8_t scan_duration)
{
    /*
     * Check if the TAL is in idle state. Only in idle state it can
     * accept and ED request from the MAC.
     */
    if (TAL_IDLE != tal_state)
    {
        if (tal_trx_status == TRX_SLEEP)
        {
            return TAL_TRX_ASLEEP;
        }
        else
        {
            ASSERT("TAL is TAL_BUSY" == 0);
            return TAL_BUSY;
        }
    }

    set_trx_state(CMD_FORCE_PLL_ON);
    pal_trx_bit_write(SR_RX_PDT_DIS, RX_DISABLE);
    pal_trx_irq_flag_clr_cca_ed();
    pal_trx_irq_init_cca_ed((FUNC_PTR)trx_ed_irq_handler_cb);
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_CCA_ED_READY);

    /* Make sure that receiver is switched on. */
    if (set_trx_state(CMD_RX_ON) != RX_ON)
    {
        /* Restore previous configuration */
        pal_trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);
        pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);

        return FAILURE;
    }

    /* Perform ED in TAL_ED_RUNNING state. */
    tal_state = TAL_ED_RUNNING;

    max_ed_level = 0;   // reset max value

    sampler_counter = CALCULATE_SYMBOL_TIME_SCAN_DURATION(scan_duration) / ED_SAMPLE_DURATION_SYM;

    // write dummy value to start measurement
    pal_trx_reg_write(RG_PHY_ED_LEVEL, 0xFF);

    return MAC_SUCCESS;
}
Пример #17
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. */
    pal_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.
     */
    pal_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 = pal_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.
     */
    pal_trx_reg_write(RG_IRQ_STATUS, 0xFF);
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);

    /* Set the seed for the random number generator. */
    srand(seed);
}
Пример #18
0
/**
 * @brief Switches the PLL on
 */
static void switch_pll_on(void)
{
    trx_irq_reason_t irq_status;
    uint32_t start_time, now;

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

    /* use the IRQ status register checking for the actual PLL status */
    pal_trx_irq_dis();
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_PLL_LOCK);  /* allow PLL lock IRQ only*/
    pal_trx_reg_read(RG_IRQ_STATUS);    /* clear PLL lock bit */

    /* Switch PLL on */
    pal_trx_reg_write(RG_TRX_STATE, CMD_PLL_ON);

    /* Check if PLL has been locked. */
    pal_get_current_time(&start_time);
    while (1)
    {
        irq_status = (trx_irq_reason_t)pal_trx_reg_read(RG_IRQ_STATUS);
        if (irq_status & TRX_IRQ_PLL_LOCK)
        {
            break;  // PLL is locked now
        }

        /* Check if polling needs too much time. */
        pal_get_current_time(&now);
        if (pal_sub_time_us(now, start_time) > (10 * PLL_LOCK_TIME_US))
        {
            /* leave poll loop and throw assertion */
#if (DEBUG > 0)
            ASSERT("PLL switch failed" == 0);
#endif
            break;
        }
    }
    pal_trx_irq_flag_clr();
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_TRX_END); /* enable TRX_END interrupt */

    pal_trx_irq_en();
}
Пример #19
0
/*
 * \brief Perform a single ED measurement
 *
 * \return ed_value Result of the measurement
 *         If the build switch TRX_REG_RAW_VALUE is defined, the transceiver's
 *         register value is returned.
 */
uint8_t tfa_ed_sample(void)
{
    uint8_t ed_value;
    tal_trx_status_t trx_status;

    /* Make sure that receiver is switched on. */
    do
    {
        trx_status = set_trx_state(CMD_RX_ON);
    }
    while (trx_status != RX_ON);

    /*
     * Disable the transceiver interrupts to prevent frame reception
     * while performing ED scan.
     */
    pal_trx_irq_dis();

    /*
     * Initiate ED operation by writing any value into transceiver register
     * PHY_ED_LEVEL.
     */
    pal_trx_reg_write(RG_PHY_ED_LEVEL, 0x00);

    /*
     * Start timer for reading ED value from the transceiver after
     * 140 microseconds.
     */
    pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(ED_SAMPLE_DURATION_SYM + 1));

    /* Read the ED Value. */
    ed_value = pal_trx_reg_read(RG_PHY_ED_LEVEL);

    /* Clear IRQ register */
    pal_trx_reg_read(RG_IRQ_STATUS);
    /* Enable reception agian */
    pal_trx_irq_flag_clr();
    pal_trx_irq_en();
    /* Switch receiver off again */
    set_trx_state(CMD_TRX_OFF);

#ifndef TRX_REG_RAW_VALUE
    /*
     * Scale ED result.
     * Clip values to 0xFF if > -35dBm
     */
    if (ed_value > CLIP_VALUE_REG)
    {
        ed_value = 0xFF;
    }
    else
    {
        ed_value = (uint8_t)(((uint16_t)ed_value * 0xFF) / CLIP_VALUE_REG);
    }
#endif

    return ed_value;
}
Пример #20
0
/**
 * @brief Perform a single ED measurement
 *
 * @return ed_value Result of the measurement
 *         If the build switch TRX_REG_RAW_VALUE is defined, the transceiver's
 *         register value is returned.
 */
uint8_t tfa_ed_sample(void)
{
    trx_irq_reason_t trx_irq_cause;
    uint8_t ed_value;
    tal_trx_status_t trx_status;

    /* Make sure that receiver is switched on. */
    do
    {
        trx_status = set_trx_state(CMD_RX_ON);
    }
    while (trx_status != RX_ON);

    /*
     * Disable the transceiver interrupts to prevent frame reception
     * while performing ED scan.
     */
    pal_trx_bit_write(SR_RX_PDT_DIS, RX_DISABLE);

    /* Write dummy value to start measurement. */
    pal_trx_reg_write(RG_PHY_ED_LEVEL, 0xFF);

    /* Wait for ED measurement completion. */
    pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(ED_SAMPLE_DURATION_SYM));
    do
    {
        trx_irq_cause = (trx_irq_reason_t)pal_trx_reg_read(RG_IRQ_STATUS);
    }
    while ((trx_irq_cause & TRX_IRQ_CCA_ED_READY) != TRX_IRQ_CCA_ED_READY);

    /* Read the ED Value. */
    ed_value = pal_trx_reg_read(RG_PHY_ED_LEVEL);

#ifndef TRX_REG_RAW_VALUE
    /*
     * Scale ED result.
     * Clip values to 0xFF if > -35dBm
     */
    if (ed_value > CLIP_VALUE_REG)
    {
        ed_value = 0xFF;
    }
    else
    {
        ed_value = (uint8_t)(((uint16_t)ed_value * 0xFF) / CLIP_VALUE_REG);
    }
#endif

    /* Clear IRQ register */
    pal_trx_reg_read(RG_IRQ_STATUS);
    /* Enable reception agian */
    pal_trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);
    /* Switch receiver off again */
    set_trx_state(CMD_TRX_OFF);

    return ed_value;
}
Пример #21
0
/**
 * @brief Write all shadow PIB variables to the transceiver
 *
 * This function writes all shadow PIB variables to the transceiver.
 * It is assumed that the radio does not sleep.
 */
void write_all_tal_pib_to_trx(void)
{
    uint8_t *ptr_to_reg;

    /* configure RX_AACK */
    ptr_to_reg = (uint8_t *)&tal_pib.PANId;
    for (uint8_t i = 0; i < 2; i++)
    {
        pal_trx_reg_write((RG_PAN_ID_0 + i), *ptr_to_reg);
        ptr_to_reg++;
    }

    ptr_to_reg = (uint8_t *)&tal_pib.IeeeAddress;
    for (uint8_t i = 0; i < 8; i++)
    {
        pal_trx_reg_write((RG_IEEE_ADDR_0 + i), *ptr_to_reg);
        ptr_to_reg++;
    }

    ptr_to_reg = (uint8_t *)&tal_pib.ShortAddress;
    for (uint8_t i = 0; i < 2; i++)
    {
        pal_trx_reg_write((RG_SHORT_ADDR_0 + i), *ptr_to_reg);
        ptr_to_reg++;
    }

    /* configure TX_ARET; CSMA and CCA */
    {
        uint8_t reg_value;

        reg_value = convert_phyTransmitPower_to_reg_value(tal_pib.TransmitPower);
        pal_trx_bit_write(SR_TX_PWR, reg_value);
    }
    pal_trx_bit_write(SR_CCA_MODE, tal_pib.CCAMode);
    pal_trx_bit_write(SR_CHANNEL, tal_pib.CurrentChannel);
    pal_trx_bit_write(SR_MIN_BE, tal_pib.MinBE);

#ifdef PROMISCUOUS_MODE
    if (tal_pib.PromiscuousMode)
    {
        set_trx_state(CMD_RX_ON);
    }
#endif
}
Пример #22
0
/**
 * @brief Write all shadow PIB variables to the transceiver
 *
 * This function writes all shadow PIB variables to the transceiver.
 * It is assumed that the radio does not sleep.
 */
void write_all_tal_pib_to_trx(void)
{
    uint8_t *ptr_to_reg;

    pal_trx_reg_write(RG_PAN_ID_0, (uint8_t)tal_pib_PANId);
    pal_trx_reg_write(RG_PAN_ID_1, (uint8_t)(tal_pib_PANId >> 8));

    ptr_to_reg = (uint8_t *)&tal_pib_IeeeAddress;
    for (uint8_t i = 0; i < 8; i++)
    {
        pal_trx_reg_write((RG_IEEE_ADDR_0 + i), *ptr_to_reg);
        ptr_to_reg++;
    }

    pal_trx_reg_write(RG_SHORT_ADDR_0, (uint8_t)tal_pib_ShortAddress);
    pal_trx_reg_write(RG_SHORT_ADDR_1, (uint8_t)(tal_pib_ShortAddress >> 8));

    /* configure TX_ARET; CSMA and CCA */
    pal_trx_bit_write(SR_CCA_MODE, tal_pib_CCAMode);
    pal_trx_bit_write(SR_MIN_BE, tal_pib_MinBE);

    pal_trx_bit_write(SR_AACK_I_AM_COORD, tal_pib_PrivatePanCoordinator);

    /* set phy parameter */
    pal_trx_bit_write(SR_MAX_BE, tal_pib_MaxBE);
    apply_channel_page_configuration(tal_pib_CurrentPage);

    {
        uint8_t reg_value;

        reg_value = convert_phyTransmitPower_to_reg_value(tal_pib_TransmitPower);
        pal_trx_reg_write(RG_PHY_TX_PWR, reg_value);
    }

#ifdef PROMISCUOUS_MODE
    if (tal_pib_PromiscuousMode)
    {
        set_trx_state(CMD_RX_ON);
    }
#endif
}
Пример #23
0
/*
 * \brief Starts continuous transmission on current channel
 *
 * \param tx_mode Mode of continuous transmission (CW or PRBS)
 * \param random_content Use random content if true
 */
void tfa_continuous_tx_start(continuous_tx_mode_t tx_mode, bool random_content)
{
    uint8_t txcwdata[128];

    pal_trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
    pal_trx_bit_write(SR_TX_AUTO_CRC_ON, TX_AUTO_CRC_DISABLE);
    pal_trx_reg_write(0x36, 0x0F);     /* TST_CTRL_DIGI */

    if (tx_mode == CW_MODE)
    {
        txcwdata[0] = 1;    // step 9
        txcwdata[1] = 0;
        pal_trx_frame_write(txcwdata, 2);
        // Step 10
        pal_trx_reg_write(0x3D, 0x80);  /* Configure continuous Tx (2) */
    }
    else    // PRBS mode
    {
        txcwdata[0] = 127;   // = max length
        for (uint8_t i = 1; i < 128; i++)
        {
            if (random_content)
            {
                txcwdata[i] = (uint8_t)rand();
            }
            else
            {
                txcwdata[i] = 0;
            }
        }
        pal_trx_frame_write(txcwdata, 128);
        pal_trx_reg_write(0x3D, 0x00);  /* Configure continuous Tx (2) */
    }

    // set tst pin to high
    TST_PORT_HIGH();

    set_trx_state(CMD_PLL_ON);
    PAL_SLP_TR_HIGH();
    PAL_SLP_TR_LOW();
}
Пример #24
0
/**
 * \brief Test the read and write of register on AT86RFx module
 *
 * This function will test the read and write functionalities of register
 * It will first write a known value (state) to register and reads the
 * register to confirm the same value.
 *
 * \param test Current test case.
 */
static void run_at86rfx_reg_access_test(const struct test_case *test)
{
	bool status;
	trx_cmd_t value;

	pal_trx_reg_write(RG_TRX_STATE, CMD_RX_ON);

	value = (trx_cmd_t) pal_trx_reg_read(RG_TRX_STATE);
	status = (CMD_RX_ON == value) ? true : false;
	test_assert_true(test, status == true,
			"Error Read/write AT86RFx register access failed");
}
Пример #25
0
/**
 * @brief Subregister write
 *
 * @param[in] reg_addr Offset of the register
 * @param[in] mask Bit mask of the subregister
 * @param[in] pos Bit position of the subregister
 * @param[out] new_value Data, which is muxed into the register
 */
void pal_trx_bit_write(uint8_t reg_addr, uint8_t mask, uint8_t pos, uint8_t new_value)
{
    uint8_t current_reg_value;

    current_reg_value = pal_trx_reg_read(reg_addr);
    current_reg_value &= (uint8_t)~(uint32_t)mask;  // Implicit casting required to avoid IAR Pa091.
    new_value <<= pos;
    new_value &= mask;
    new_value |= current_reg_value;

    pal_trx_reg_write(reg_addr, new_value);
}
Пример #26
0
static trx_retval_t trx_init(void)
{
	tal_trx_status_t trx_status;
	uint8_t poll_counter = 0;

	/* Ensure control lines have correct levels. */
	RST_HIGH();
	SLP_TR_LOW();

	/* Wait typical time. */
	DELAY_US(P_ON_TO_CLKM_AVAILABLE_TYP_US);

	/* Apply reset pulse */
	RST_LOW();
	DELAY_US(RST_PULSE_WIDTH_US);
	RST_HIGH();

	/* Verify that TRX_OFF can be written */
	do {
		/* Wait not more than max. value of TR1. */
		if (poll_counter == P_ON_TO_CLKM_ATTEMPTS) {
			return TRX_FAILURE;
		}
		/* Wait a short time interval. */
		DELAY_US(TRX_POLL_WAIT_TIME_US);
		poll_counter++;
		/* Check if AT86RF212 is connected; omit manufacturer id check */
	}
	while (pal_trx_reg_read(RG_PART_NUM) != PART_NUM_AT86RF212);

	/* Set trx to off mode */
	pal_trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);

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

		trx_status = (tal_trx_status_t) pal_trx_bit_read(SR_TRX_STATUS);

		/* Wait not more than max attempts for state transition */
		if (poll_counter == SLEEP_TO_TRX_OFF_ATTEMPTS) {
			return TRX_FAILURE;
		}
		poll_counter++;
	} while (trx_status != TRX_OFF);

	tal_trx_status = TRX_OFF;

	return TRX_SUCCESS;
}
Пример #27
0
/**
 * \brief Finalizes the CSMA procedure
 *
 * \param status Result of the slotted transmission
 */
static void tx_done(retval_t status)
{
#if (_DEBUG_ > 0)
	switch (tal_state) {
	case TAL_SLOTTED_CSMA:
	case TAL_TX_BASIC:
		break;

#if ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT))
	case TAL_TX_BEACON:
		Assert("unexpected tal_state TAL_TX_BEACON" == 0);
		return;

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

	default:
		Assert("unexpected tal_state" == 0);
		break;
	}
#endif
#if (_DEBUG_ > 0)
	if (pal_is_timer_running(TAL_CSMA_BEACON_LOSS_TIMER)) {
		Assert("beacon lost timer is still running" == 0);
	}

#endif

	tal_state = TAL_IDLE;
	tal_csma_state = CSMA_IDLE;

	/*
	 * Restore the interrupt handler.
	 * Install a handler for the transceiver interrupt.
	 */
	pal_trx_irq_init((FUNC_PTR)trx_irq_handler_cb);
	pal_trx_reg_read(RG_IRQ_STATUS);

	/* Check if a receive buffer is available. */
	if (NULL != tal_rx_buffer) {
		pal_trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON);
	} else {
		tal_rx_on_required = true;
	}

	pal_trx_irq_en();

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

	tal_tx_frame_done_cb(status, mac_frame_ptr);
}
Пример #28
0
/**
 * \brief Configures the transceiver
 *
 * This function is called to configure the transceiver after reset.
 */
static void trx_config(void)
{
    /* Set pin driver strength */
    pal_trx_reg_write(RG_TRX_CTRL_0, ((CLKM_2mA << 6) |
                                      (CLKM_2mA << 4) | CLKM_1MHz));               /* fast
	                                                              * change */

    /*
     * Init the SEED value of the CSMA backoff algorithm.
     */
    uint16_t rand_value = (uint16_t)rand();
    pal_trx_reg_write(RG_CSMA_SEED_0, (uint8_t)rand_value);
    pal_trx_bit_write(SR_CSMA_SEED_1, (uint8_t)(rand_value >> 8));

    /*
     * 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();

    pal_trx_bit_write(SR_AACK_SET_PD, PD_ACK_BIT_SET_ENABLE); /* 1 == frame
	                                                           *pending bit
	                                                           *is always
	                                                           *set to 1 */
    pal_trx_bit_write(SR_TX_AUTO_CRC_ON, TX_AUTO_CRC_ENABLE); /* enable auto
	                                                           *crc */
    pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_TRX_END); /* enable TRX_END
	                                                  *interrupt */

#ifdef CCA_ED_THRESHOLD

    /*
     * Set CCA ED Threshold to other value than standard register due to
     * board specific loss (see pal_config.h). */
    pal_trx_bit_write(SR_CCA_ED_THRES, CCA_ED_THRESHOLD);
#endif
}
Пример #29
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;

    PAL_RST_HIGH();
    PAL_SLP_TR_LOW();

    pal_timer_delay(P_ON_TO_CLKM_AVAILABLE);

    /* apply reset pulse */
    PAL_RST_LOW();
    pal_timer_delay(RST_PULSE_WIDTH_US);
    PAL_RST_HIGH();

    /* Verify that TRX_OFF can be written */
    do {
        if (poll_counter == 0xFF) {
            return FAILURE;
        }

        /* Wait a short time interval. */
        pal_timer_delay(TRX_POLL_WAIT_TIME_US);
        poll_counter++;
        /* Check if AT86RF230 is connected; omit manufacturer id check
         **/
    } while ((pal_trx_reg_read(RG_VERSION_NUM) != AT86RF230_REV_B) ||
             (pal_trx_reg_read(RG_PART_NUM) != AT86RF230));

    pal_trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);

    /* verify that trx has reached TRX_OFF */
    poll_counter = 0;
    do {
        trx_status = (tal_trx_status_t)pal_trx_bit_read(SR_TRX_STATUS);
        if (poll_counter == 0xFF) {
#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;
}
Пример #30
0
/*
 * \brief handling of CCA result.
 */
void cca_done_handling(void)
{
	set_trx_state(CMD_PLL_ON); /* leave RX_ON */
	/* Restore IRQ handling */
	pal_trx_irq_init((FUNC_PTR)trx_irq_handler_cb);
	pal_trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT);
	pal_trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE); /* Enable frame reception.
	                                              **/

	/* Check if channel was idle or busy */
	if (pal_trx_bit_read(SR_CCA_STATUS) == CCA_STATUS_CHANNEL_IS_IDLE) {
		tx_frame();
	} else {
		tal_state = TAL_CSMA_CONTINUE;
	}
}