Beispiel #1
0
/*
 * \brief Sets a TFA PIB attribute
 *
 * This function is called to set the transceiver information base
 * attributes.
 *
 * \param[in] tfa_pib_attribute TFA infobase attribute ID
 * \param[in] value TFA infobase attribute value to be set
 *
 * \return MAC_UNSUPPORTED_ATTRIBUTE if the TFA info base attribute is not found
 *         TAL_BUSY if the TAL is not in TAL_IDLE state.
 *         MAC_SUCCESS if the attempt to set the PIB attribute was successful
 */
retval_t tfa_pib_set(tfa_pib_t tfa_pib_attribute, void *value)
{
	switch (tfa_pib_attribute) {
	case TFA_PIB_RX_SENS:
	{
		uint8_t reg_val;

		tfa_pib_rx_sens = *((int8_t *)value);
		if (tfa_pib_rx_sens > -49) {
			reg_val = 0xF;
			tfa_pib_rx_sens = -49;
		} else if (tfa_pib_rx_sens <= RSSI_BASE_VAL_DBM) {
			reg_val = 0x0;
			tfa_pib_rx_sens = RSSI_BASE_VAL_DBM;
		} else {
			reg_val
				= ((tfa_pib_rx_sens -
					(RSSI_BASE_VAL_DBM)) / 3) + 1;
		}

		trx_bit_write(SR_RX_PDT_LEVEL, reg_val);
		CONF_REG_WRITE();
	}
	break;

	default:
		/* Invalid attribute id */
		return MAC_UNSUPPORTED_ATTRIBUTE;
	}

	return MAC_SUCCESS;
}
Beispiel #2
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.
	 */
	trx_bit_write(SR_RX_PDT_DIS, RX_DISABLE);
	CONF_REG_WRITE();
	/* Write dummy value to start measurement. */
	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)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 = 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 */
	trx_reg_read(RG_IRQ_STATUS);
	/* Enable reception agian */
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);
	/* Switch receiver off again */
	set_trx_state(CMD_TRX_OFF);

	return ed_value;
}
Beispiel #3
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);

#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);
    }

    CONF_REG_WRITE();

#ifdef PROMISCUOUS_MODE
    if (tal_pib.PromiscuousMode)
    {
        set_trx_state(CMD_RX_ON);
    }
#endif
}
Beispiel #4
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;
	}
}
Beispiel #5
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_COMPLETED);

	set_trx_state(CMD_TRX_OFF);

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

	/* Enable frame reception again. */
	trx_bit_write(SR_RX_PDT_DIS, RX_ENABLE);
	CONF_REG_WRITE();
	return (phy_enum_t)cca_status;
}
Beispiel #6
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;
	}
}
/*
 * \brief Handle received frame interrupt
 *
 * This function handles transceiver interrupts for received frames and
 * uploads the frames from the trx.
 */
void handle_received_frame_irq(void)
{
	uint8_t ed_value;
	/* Actual frame length of received frame. */
	uint8_t phy_frame_len;
	/* Extended frame length appended by LQI and ED. */
	uint8_t ext_frame_length;
	frame_info_t *receive_frame;
	uint8_t *frame_ptr;

	if (tal_rx_buffer == NULL) {
		Assert("no tal_rx_buffer available" == 0);

		/*
		 * Although the buffer protection mode is enabled and the
		 *receiver has
		 * been switched to PLL_ON, the next incoming frame was faster.
		 * It cannot be handled and is discarded.
		 */
		trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_DISABLE); /* Disable
		                                                       *buffer
		                                                       *protection
		                                                       *mode */
		CONF_REG_WRITE();
		pal_timer_delay(2); /* Allow pin change to get effective */
		trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE); /* Enable
		                                                      *buffer
		                                                      *protection
		                                                      *mode */
		CONF_REG_WRITE();
		return;
	}

	receive_frame = (frame_info_t *)BMM_BUFFER_POINTER(tal_rx_buffer);

#ifdef PROMISCUOUS_MODE
	if (tal_pib.PromiscuousMode) {
		/* Check for valid FCS */
		if (trx_bit_read(SR_RX_CRC_VALID) == CRC16_NOT_VALID) {
			return;
		}
	}

#endif

	/* Get ED value; needed to normalize LQI. */
	ed_value = trx_reg_read(RG_PHY_ED_LEVEL);

	/* Get frame length from transceiver. */
	phy_frame_len = ext_frame_length = trx_reg_read(RG_TST_RX_LENGTH);

	/* Check for valid frame length. */
	if (phy_frame_len > 127) {
		return;
	}

	/*
	 * The PHY header is also included in the frame (length field), hence
	 *the frame length
	 * is incremented.
	 * In addition to that, the LQI and ED value are uploaded, too.
	 */
	ext_frame_length += LQI_LEN + ED_VAL_LEN;

	/* Update payload pointer to store received frame. */
	frame_ptr = (uint8_t *)receive_frame + LARGE_BUFFER_SIZE -
			ext_frame_length;

	/*
	 * Note: The following code is different from other non-single chip
	 * transceivers, where reading the frame via SPI contains the length
	 *field
	 * in the first octet.
	 */
	trx_frame_read(frame_ptr, phy_frame_len + LQI_LEN);
	frame_ptr--;
	*frame_ptr = phy_frame_len;
	receive_frame->mpdu = frame_ptr;
	/* Add ED value at the end of the frame buffer. */
	receive_frame->mpdu[phy_frame_len + LQI_LEN + ED_VAL_LEN] = ed_value;

#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)

	/*
	 * Store the timestamp.
	 * The timestamping is only required for beaconing networks
	 * or if timestamping is explicitly enabled.
	 */
	receive_frame->time_stamp = tal_rx_timestamp;
#endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

	/* Append received frame to incoming_frame_queue and get new rx buffer.
	 **/
	qmm_queue_append(&tal_incoming_frame_queue, tal_rx_buffer);

	/* The previous buffer is eaten up and a new buffer is not assigned yet.
	 **/
	tal_rx_buffer = bmm_buffer_alloc(LARGE_BUFFER_SIZE);

	/* Check if receive buffer is available */
	if (NULL == tal_rx_buffer) {
		/* Do not change the state since buffer protection mode is not
		 * re-enabled yet.
		 * Buffer protection will be re-enabled after buffer becomes
		 *available
		 */
		/* set_trx_state(CMD_PLL_ON); */
		tal_rx_on_required = true;
	} else {
		/*
		 * Trx returns to RX_AACK_ON automatically, if this was its
		 *previous state.
		 * Keep the following as a reminder, if receiver is used with
		 *RX_ON instead.
		 */
		/* trx_reg_write(RG_TRX_STATE, CMD_RX_AACK_ON); */

		/*
		 * Release the protected buffer and set it again for further
		 *protection since
		 * the buffer is available
		 */
		trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_DISABLE); /* Disable
		                                                       *buffer
		                                                       *protection
		                                                       *mode */
		pal_timer_delay(2); /* Allow pin change to get effective */
		trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE); /* Enable
		                                                      *buffer
		                                                      *protection
		                                                      *mode */

		CONF_REG_WRITE();
	}

	/*
	 * Clear pending TX_END IRQ: The TX_END IRQ is envoked for the
	 *transmission
	 * end of an automatically sent ACK frame. This implementation does not
	 *use
	 * this feature.
	 */
	pal_trx_irq_flag_clr_tx_end();
}
Beispiel #8
0
/*
 * \brief Sends frame
 *
 * \param use_csma Flag indicating if CSMA is requested
 * \param tx_retries Flag indicating if transmission retries are requested
 *                   by the MAC layer
 */
void send_frame(csma_mode_t csma_mode, bool tx_retries)
{
	tal_trx_status_t trx_status;

	/* Configure tx according to tx_retries */
	if (tx_retries) {
		trx_bit_write(SR_MAX_FRAME_RETRIES, tal_pib.MaxFrameRetries);
	} else {
		trx_bit_write(SR_MAX_FRAME_RETRIES, 0);
	}

	/* Configure tx according to csma usage */
	if ((csma_mode == NO_CSMA_NO_IFS) || (csma_mode == NO_CSMA_WITH_IFS)) {
		if (tx_retries) {
			trx_bit_write(SR_MAX_CSMA_RETRIES,
					tal_pib.MaxCSMABackoffs);
			trx_reg_write(RG_CSMA_BE, 0x00);
		} else {
			trx_bit_write(SR_MAX_CSMA_RETRIES, 7);
		}
	} else {
		trx_reg_write(RG_CSMA_BE,
				((tal_pib.MaxBE << 4) | tal_pib.MinBE));
		trx_bit_write(SR_MAX_CSMA_RETRIES, tal_pib.MaxCSMABackoffs);
	}

	CONF_REG_WRITE();

	do {
		trx_status = set_trx_state(CMD_TX_ARET_ON);
	} while (trx_status != TX_ARET_ON);

	/* Handle interframe spacing */
	if (csma_mode == NO_CSMA_WITH_IFS) {
		if (last_frame_length > aMaxSIFSFrameSize) {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinLIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		} else {
			pal_timer_delay(TAL_CONVERT_SYMBOLS_TO_US(
					macMinSIFSPeriod_def)
					- IRQ_PROCESSING_DLY_US -
					PRE_TX_DURATION_US);
			last_frame_length = 0;
		}
	} else {
		/*
		 * If no delay is applied after switching to TX_ARET_ON,
		 * a short delay is required that allows that a pending TX_END
		 *IRQ for
		 * ACK transmission gets served.
		 */
		pal_timer_delay(TRX_IRQ_DELAY_US);
	}

	ENTER_CRITICAL_REGION(); /* prevent from buffer underrun */

	/* Toggle the SLP_TR pin triggering transmission. */
	TRX_SLP_TR_HIGH();
	PAL_WAIT_65_NS();
	TRX_SLP_TR_LOW();

	/*
	 * Send the frame to the transceiver.
	 * Note: The PhyHeader is the first byte of the frame to
	 * be sent to the transceiver and this contains the frame
	 * length.
	 */
	trx_frame_write(tal_frame_to_tx, tal_frame_to_tx[0] - 1);

	tal_state = TAL_TX_AUTO;

	LEAVE_CRITICAL_REGION();
}
Beispiel #9
0
/*
 * \brief TAL task handling
 *
 * This function
 * - Checks and allocates the receive buffer.
 * - Processes the TAL incoming frame queue.
 * - Implements the TAL state machine.
 */
void tal_task(void)
{
	/* Check if the receiver needs to be switched on. */
	if (tal_rx_on_required && (tal_state == TAL_IDLE)) {
		/* Check if a receive buffer has not been available before. */
		if (tal_rx_buffer == NULL) {
			tal_rx_buffer = bmm_buffer_alloc(LARGE_BUFFER_SIZE);
		}

		/* Check if buffer could be allocated */
		if (NULL != tal_rx_buffer) {
			/*
			 * Note:
			 * This flag needs to be reset BEFORE the received is
			 *switched on.
			 */
			tal_rx_on_required = false;

			/*
			 * Release the protected buffer and set it again for
			 *further protection
			 * since the buffer is available now.
			 */
			trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_DISABLE); /*
			                                                       *Disable
			                                                       *buffer
			                                                       *protection
			                                                       *mode
			                                                       **/
			pal_timer_delay(2); /* Allow pin change to get effective */
			trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE); /*
			                                                      *Enable
			                                                      *buffer
			                                                      *protection
			                                                      *mode
			                                                      **/

			CONF_REG_WRITE();

#ifdef PROMISCUOUS_MODE
			if (tal_pib.PromiscuousMode) {
				set_trx_state(CMD_RX_ON);
			} else {
				set_trx_state(CMD_RX_AACK_ON);
			}

#else   /* Normal operation */
			set_trx_state(CMD_RX_AACK_ON);
#endif
		}
	} else {
		/* no free buffer is available; try next time again */
	}

	/*
	 * If the transceiver has received a frame and it has been placed
	 * into the queue of the TAL, the frame needs to be processed further.
	 */
	if (tal_incoming_frame_queue.size > 0) {
		buffer_t *rx_frame;

		/* Check if there are any pending data in the
		 *incoming_frame_queue. */
		rx_frame = qmm_queue_remove(&tal_incoming_frame_queue, NULL);
		if (NULL != rx_frame) {
			process_incoming_frame(rx_frame);
		}
	}

	/* Handle the TAL state machines */
	switch (tal_state) {
	case TAL_IDLE:
	/* Do nothing, but fall through... */
	case TAL_TX_AUTO:
		/* Wait until state is changed to TAL_TX_DONE inside tx end ISR
		 **/
		break;

	case TAL_TX_DONE:
		tx_done_handling(); /* see tal_tx.c */
		break;

#ifdef BEACON_SUPPORT
	case TAL_SLOTTED_CSMA:
		slotted_csma_state_handling(); /* see tal_slotted_csma.c */
		break;
#endif  /* BEACON_SUPPORT */

#if (MAC_SCAN_ED_REQUEST_CONFIRM == 1)
	case TAL_ED_RUNNING:
		/* Do nothing here. Wait until ED is completed. */
		break;

	case TAL_ED_DONE:
		ed_scan_done();
		break;

#endif /* (MAC_SCAN_ED_REQUEST_CONFIRM == 1) */
	default:
		Assert("tal_state is not handled" == 0);
		break;
	}
} /* tal_task() */
Beispiel #10
0
/*
 * \brief Sets a TAL PIB attribute
 *
 * This function is called to set the transceiver information base
 * attributes.
 *
 * \param attribute TAL infobase attribute ID
 * \param value TAL infobase attribute value to be set
 *
 * \return MAC_UNSUPPORTED_ATTRIBUTE if the TAL info base attribute is not found
 *         TAL_BUSY if the TAL is not in TAL_IDLE state. An exception is
 *         macBeaconTxTime which can be accepted by TAL even if TAL is not
 *         in TAL_IDLE state.
 *         MAC_SUCCESS if the attempt to set the PIB attribute was successful
 *         TAL_TRX_ASLEEP if trx is in SLEEP mode and access to trx is required
 */
retval_t tal_pib_set(uint8_t attribute, pib_value_t *value)
{
    /*
     * Do not allow any changes while ED or TX is done.
     * We allow changes during RX, but it's on the user's own risk.
     */
#if (MAC_SCAN_ED_REQUEST_CONFIRM == 1)
    if (tal_state == TAL_ED_RUNNING)
    {
        Assert("TAL is busy" == 0);
        return TAL_BUSY;
    }
#endif /* (MAC_SCAN_ED_REQUEST_CONFIRM == 1) */

    /*
     * Distinguish between PIBs that need to be changed in trx directly
     * and those that are simple variable udpates.
     * Ensure that the transceiver is not in SLEEP.
     * If it is in SLEEP, change it to TRX_OFF.
     */

    switch (attribute)
    {
        case macMaxFrameRetries:
            /*
             * The new PIB value is not immediately written to the
             * transceiver. This is done on a frame-by-frame base.
             */
            tal_pib.MaxFrameRetries = value->pib_value_8bit;
            break;

        case macMaxCSMABackoffs:
            /*
             * The new PIB value is not immediately written to the
             * transceiver. This is done on a frame-by-frame base.
             */
            tal_pib.MaxCSMABackoffs = value->pib_value_8bit;
            break;

#ifdef BEACON_SUPPORT
        case macBattLifeExt:
            tal_pib.BattLifeExt = value->pib_value_bool;
            break;

        case macBeaconOrder:
            tal_pib.BeaconOrder = value->pib_value_8bit;
            break;

        case macSuperframeOrder:
            tal_pib.SuperFrameOrder = value->pib_value_8bit;
            break;

        case macBeaconTxTime:
            tal_pib.BeaconTxTime = value->pib_value_32bit;
            break;

#endif  /* BEACON_SUPPORT */
#ifdef PROMISCUOUS_MODE
        case macPromiscuousMode:
            tal_pib.PromiscuousMode = value->pib_value_8bit;
            if (tal_pib.PromiscuousMode)
            {
                tal_trx_wakeup();

                /* Check if receive buffer is available or queue is not full. */
                if (NULL == tal_rx_buffer)
                {
                    set_trx_state(CMD_PLL_ON);
                    tal_rx_on_required = true;
                }
                else
                {
                    set_trx_state(CMD_RX_ON);
                }
            }
            else
            {
                set_trx_state(CMD_TRX_OFF);
                tal_rx_on_required = false;
            }
            break;
#endif

        default:
            /*
             * Following PIBs require access to trx.
             * Therefore trx must be at least in TRX_OFF.
             */

            if (tal_trx_status == TRX_SLEEP)
            {
                /* While trx is in SLEEP, register cannot be accessed. */
                return TAL_TRX_ASLEEP;
            }

            switch (attribute)
            {
                case macMinBE:
                    tal_pib.MinBE = value->pib_value_8bit;

#ifndef REDUCED_PARAM_CHECK
                    /*
                     * macMinBE must not be larger than macMaxBE or calculation
                     * of macMaxFrameWaitTotalTime will fail.
                     */
                    if (tal_pib.MinBE > tal_pib.MaxBE)
                    {
                        tal_pib.MinBE = tal_pib.MaxBE;
                    }
#endif  /* REDUCED_PARAM_CHECK */

                    pal_trx_bit_write(SR_MIN_BE, tal_pib.MinBE);
                    break;

                case macPANId:
                    tal_pib.PANId = value->pib_value_16bit;
                    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));
                    break;

                case macShortAddress:
                    tal_pib.ShortAddress = value->pib_value_16bit;
                    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));
                    break;

                case phyCurrentChannel:
                    if (tal_state != TAL_IDLE)
                    {
                        return TAL_BUSY;
                    }
                    if ((uint32_t)TRX_SUPPORTED_CHANNELS & ((uint32_t)0x01 << value->pib_value_8bit))
                    {
                        tal_trx_status_t previous_trx_status = TRX_OFF;
                        /*
                         * Set trx to "soft" off avoiding that ongoing
                         * transaction (e.g. ACK) are interrupted.
                         */
                        if (tal_trx_status != TRX_OFF)
                        {
                            previous_trx_status = RX_AACK_ON;   /* any other than TRX_OFF state */
                            do
                            {
                                /* set TRX_OFF until it could be set;
                                 * trx might be busy */
                            }
                            while (set_trx_state(CMD_TRX_OFF) != TRX_OFF);
                        }
                        tal_pib.CurrentChannel = value->pib_value_8bit;
                        pal_trx_bit_write(SR_CHANNEL, tal_pib.CurrentChannel);
                        /* Re-store previous trx state */
                        if (previous_trx_status != TRX_OFF)
                        {
                            /* Set to default state */
                            set_trx_state(CMD_RX_AACK_ON);
                        }
                    }
                    else
                    {
                        return MAC_INVALID_PARAMETER;
                    }
                    break;

                case phyCurrentPage:
#ifdef HIGH_DATA_RATE_SUPPORT
                    if (tal_state != TAL_IDLE)
                    {
                        return TAL_BUSY;
                    }
                    else
                    {
                        uint8_t page;
                        tal_trx_status_t previous_trx_status = TRX_OFF;
                        bool ret_val;

                        /*
                         * Changing the channel, channel page or modulation
                         * requires that TRX is in TRX_OFF.
                         * Store current trx state and return to default state
                         * after channel page has been set.
                         */
                        if (tal_trx_status != TRX_OFF)
                        {
                            previous_trx_status = RX_AACK_ON;   /* any other than TRX_OFF state */
                            do
                            {
                                /* set TRX_OFF until it could be set;
                                 * trx might be busy */
                            }
                            while (set_trx_state(CMD_TRX_OFF) != TRX_OFF);
                        }

                        page = value->pib_value_8bit;

                        ret_val = apply_channel_page_configuration(page);

                        if (previous_trx_status != TRX_OFF)
                        {
                            /* Set to default state */
                            set_trx_state(CMD_RX_AACK_ON);
                        }

                        if (ret_val)
                        {
                            tal_pib.CurrentPage = page;
                        }
                        else
                        {
                            return MAC_INVALID_PARAMETER;
                        }
                    }
#else
                    if (tal_state != TAL_IDLE)
                    {
                        return TAL_BUSY;
                    }
                    else
                    {
                        uint8_t page;

                        page = value->pib_value_8bit;
                        if (page != 0)
                        {
                            return MAC_INVALID_PARAMETER;
                        }
                    }
#endif  /* #ifdef HIGH_DATA_RATE_SUPPORT */
                    break;

                case macMaxBE:
                    tal_pib.MaxBE = value->pib_value_8bit;
#ifndef REDUCED_PARAM_CHECK
                    /*
                     * macMinBE must not be larger than macMaxBE or calculation
                     * of macMaxFrameWaitTotalTime will fail.
                     */
                    if (tal_pib.MaxBE < tal_pib.MinBE)
                    {
                        tal_pib.MinBE = tal_pib.MaxBE;
                    }
#endif  /* REDUCED_PARAM_CHECK */
                    pal_trx_bit_write(SR_MAX_BE, tal_pib.MaxBE);
                    break;

                case phyTransmitPower:
                    {
                        uint8_t reg_value;

                        tal_pib.TransmitPower = value->pib_value_8bit;

                        /* Limit tal_pib.TransmitPower to max/min trx values */
                        tal_pib.TransmitPower = limit_tx_pwr(tal_pib.TransmitPower);
                        reg_value = convert_phyTransmitPower_to_reg_value(tal_pib.TransmitPower);
                        pal_trx_bit_write(SR_TX_PWR, reg_value);
                    }
                    break;

                case phyCCAMode:
                    tal_pib.CCAMode = value->pib_value_8bit;
                    pal_trx_bit_write(SR_CCA_MODE, tal_pib.CCAMode);
                    break;

                case macIeeeAddress:
                    {
                        uint8_t *ptr;

                        tal_pib.IeeeAddress = value->pib_value_64bit;
                        ptr = (uint8_t *)&tal_pib.IeeeAddress;

                        for (uint8_t i = 0; i < 8; i++)
                        {
                            pal_trx_reg_write((RG_IEEE_ADDR_0 + i), *ptr);
                            ptr++;
                        }
                    }
                    break;

                case mac_i_pan_coordinator:
                    tal_pib.PrivatePanCoordinator = value->pib_value_bool;
                    pal_trx_bit_write(SR_AACK_I_AM_COORD, tal_pib.PrivatePanCoordinator);
                    break;

                case macAckWaitDuration:
                    /*
                     * ATmega128RFA1 does not support changing this value w.r.t.
                     * compliance operation.
                     * The ACK timing can be reduced to 2 symbols using TFA function.
                     */
                    return MAC_UNSUPPORTED_ATTRIBUTE;

                default:
                    return MAC_UNSUPPORTED_ATTRIBUTE;
            }

            break; /* end of 'default' from 'switch (attribute)' */
    }

    CONF_REG_WRITE();
    return MAC_SUCCESS;
} /* tal_pib_set() */
Beispiel #11
0
retval_t  tal_ant_div_config(bool div_ctrl, uint8_t ant_ctrl)
{
	retval_t return_var = FAILURE;
	if (true == div_ctrl) {
		/* do the configurations if diversity has to be enabled */
		trx_bit_write(SR_ANT_CTRL, ANT_CTRL_0);
		trx_bit_write(SR_ANT_DIV_EN, ANT_DIV_ENABLE);

#if ((TAL_TYPE != AT86RF212) && (TAL_TYPE != AT86RF212B))
		trx_bit_write(SR_PDT_THRES, THRES_ANT_DIV_ENABLE);
#endif /* End of ((TAL_TYPE != AT86RF212) && (TAL_TYPE!= AT86RF212B)) */
		trx_bit_write(SR_ANT_EXT_SW_EN, ANT_EXT_SW_ENABLE);

#if (TAL_TYPE == ATMEGARFA1)
		CONF_REG_WRITE();
#endif /* TAL_TYPE == ATMEGA128RFA1 */

		/* check the values written in transceiver registers */
		if ((trx_bit_read(SR_ANT_CTRL) == ANT_CTRL_0) &&
				(trx_bit_read(SR_ANT_DIV_EN) ==
				ANT_DIV_ENABLE) && \
				(trx_bit_read(SR_ANT_EXT_SW_EN) ==
				ANT_EXT_SW_ENABLE)) {
#if ((TAL_TYPE != AT86RF212) && (TAL_TYPE != AT86RF212B))
			if ((trx_bit_read(SR_PDT_THRES) ==
					THRES_ANT_DIV_ENABLE))
#endif
			return_var = MAC_SUCCESS;
		} else {
			return_var = FAILURE;
		}
	} else {
		/* do the configurations if diversity has to be disabled */
		trx_bit_write(SR_ANT_DIV_EN, ANT_DIV_DISABLE);
#if ((TAL_TYPE != AT86RF212) && (TAL_TYPE != AT86RF212B))
		trx_bit_write(SR_PDT_THRES, THRES_ANT_DIV_DISABLE);
#endif

		trx_bit_write(SR_ANT_EXT_SW_EN, ANT_EXT_SW_ENABLE);
		if (ant_ctrl == ANT_CTRL_1) {
			/* Enable A1/X2 */
			trx_bit_write(SR_ANT_CTRL, ANT_CTRL_1);
		} else if (ant_ctrl == ANT_CTRL_2) {
			/* Enable A2/X3 */
			trx_bit_write(SR_ANT_CTRL, ANT_CTRL_2);
		} else if (ant_ctrl == ANT_CTRL_0 || ant_ctrl == ANT_CTRL_3) {
			trx_bit_write(SR_ANT_CTRL, ANT_CTRL_0);
			ant_ctrl = 0;
		} else {
			return_var = MAC_INVALID_PARAMETER;
		}

#if (TAL_TYPE == ATMEGARFA1)
		CONF_REG_WRITE();
#endif /* TAL_TYPE == ATMEGA128RFA1 */
		/* check the values written in transceiver registers */
		if ((trx_bit_read(SR_ANT_CTRL) == ant_ctrl) &&
				(trx_bit_read(SR_ANT_DIV_EN) ==
				ANT_DIV_DISABLE) && \
				(trx_bit_read(SR_ANT_EXT_SW_EN) ==
				ANT_EXT_SW_DISABLE)) {
#if ((TAL_TYPE != AT86RF212) && (TAL_TYPE != AT86RF212B))
			if ((trx_bit_read(SR_PDT_THRES) ==
					THRES_ANT_DIV_ENABLE))
#endif
			return_var = MAC_SUCCESS;
		} else {
			return_var = FAILURE;
		}
	}

	return return_var;
}