Exemple #1
0
/**
 * @brief Resets TAL state machine and sets the default PIB values if requested
 *
 * @param set_default_pib Defines whether PIB values need to be set
 *                        to its default values
 *
 * @return MAC_SUCCESS  if the transceiver state is changed to TRX_OFF
 *         FAILURE otherwise
 */
retval_t tal_reset(bool set_default_pib)
{
    /*
     * Do the reset stuff.
     * Set the default PIBs depending on the given parameter set_default_pib.
     * Do NOT generate random seed again.
     */
    if (internal_tal_reset(set_default_pib) != MAC_SUCCESS)
    {
        return FAILURE;
    }

#if (NUMBER_OF_TAL_TIMERS > 0)
    /* Clear all running TAL timers. */
    {
        uint8_t timer_id;

        ENTER_CRITICAL_REGION();

        for (timer_id = TAL_FIRST_TIMER_ID; timer_id <= TAL_LAST_TIMER_ID;
                timer_id++)
        {
            pal_timer_stop(timer_id);
        }

        LEAVE_CRITICAL_REGION();
    }
#endif

    /* Clear TAL Incoming Frame queue and free used buffers. */
    while (tal_incoming_frame_queue.size > 0)
    {
        buffer_t *frame = qmm_queue_remove(&tal_incoming_frame_queue, NULL);
        if (NULL != frame)
        {
            bmm_buffer_free(frame);
        }
    }

#ifdef ENABLE_TFA
    tfa_reset(set_default_pib);
#endif

    /*
     * Configure interrupt handling.  Clear all pending interrupts.
     * Handlers have been installed in tal_init(), and are never
     * uninstalled.
     */
    pal_trx_irq_flag_clr_rx_end();
    pal_trx_irq_flag_clr_tx_end();
#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)
    pal_trx_irq_flag_clr_tstamp();
#endif /* (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */
    pal_trx_irq_flag_clr_awake();

    /*
     * To make sure that the CSMA seed is properly set within the transceiver,
     * put the trx to sleep briefly and wake it up again.
     */
    tal_trx_sleep(SLEEP_MODE_1);

    tal_trx_wakeup();

#ifdef ENABLE_FTN_PLL_CALIBRATION
    {
        /* Handle PLL calibration and filter tuning. */
        retval_t timer_status;

        /* Calibration timer has already been stopped within this function. */

        /* Start periodic calibration timer.*/
        timer_status = pal_timer_start(TAL_CALIBRATION,
                                       TAL_CALIBRATION_TIMEOUT_US,
                                       TIMEOUT_RELATIVE,
                                       (FUNC_PTR)calibration_timer_handler_cb,
                                       NULL);

        if (timer_status != MAC_SUCCESS)
        {
            ASSERT("PLL calibration timer start problem" == 0);
        }
    }
#endif  /* ENABLE_FTN_PLL_CALIBRATION */

#ifdef STB_ON_SAL
    stb_restart();
#endif

    return MAC_SUCCESS;
}
Exemple #2
0
/**
 * \brief Configures the transceiver
 *
 * This function is called to configure the transceiver after reset.
 */
static void trx_config(void)
{
	/* Set pin driver strength */
	trx_bit_write(SR_PAD_IO_CLKM, PAD_CLKM_2_MA);
	trx_bit_write(SR_CLKM_SHA_SEL, CLKM_SHA_DISABLE);
	trx_bit_write(SR_CLKM_CTRL, CLKM_1MHZ);

#ifndef SW_CONTROLLED_CSMA

	/* 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();
	trx_reg_write(RG_CSMA_SEED_0, (uint8_t)rand_value);
	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();
#endif

	trx_bit_write(SR_AACK_SET_PD, PD_ACK_BIT_SET_ENABLE); /* ACKs for
	                                                       * data
	                                                       * requests,
	                                                       * indicate
	                                                       * pending data
	                                                       **/
	trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE); /* Enable
	                                                      * buffer
	                                                      * protection
	                                                      * mode */
	trx_bit_write(SR_IRQ_MASK_MODE, IRQ_MASK_MODE_ON); /* Enable poll
	                                                    * mode */
	trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT); /* The TRX_END
	                                              * interrupt of the
	                                              * transceiver is
	                                              * enabled. */

#if (ANTENNA_DIVERSITY == 1)
	/* Use antenna diversity */
	trx_bit_write(SR_ANT_CTRL, ANTENNA_DEFAULT);
	trx_bit_write(SR_PDT_THRES, THRES_ANT_DIV_ENABLE);
	trx_bit_write(SR_ANT_DIV_EN, ANT_DIV_ENABLE);
	trx_bit_write(SR_ANT_EXT_SW_EN, ANT_EXT_SW_ENABLE);
#elif (DISABLE_TSTAMP_IRQ == 0)
#if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)

	/*
	 * Use timestamping.
	 * The timestamping is only required for beaconing networks
	 * or if timestamping is explicitly enabled.
	 */
	trx_bit_write(SR_IRQ_2_EXT_EN, TIMESTAMPING_ENABLE); /* Enable
	                                                      * timestamping
	                                                      * output
	                                                      * signal. */
#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). */
	trx_bit_write(SR_CCA_ED_THRES, CCA_ED_THRESHOLD);
#endif

#ifdef EXT_RF_FRONT_END_CTRL
	/* Enable RF front end control */
	trx_bit_write(SR_PA_EXT_EN, PA_EXT_ENABLE);
#endif
}
/**
 * \brief Configures the transceiver
 *
 * This function is called to configure the transceiver after reset.
 */
static void trx_config(void)
{
	/* Set pin driver strength */
	trx_bit_write(SR_PAD_IO_CLKM, PAD_CLKM_2_MA);
	trx_bit_write(SR_CLKM_SHA_SEL, CLKM_SHA_DISABLE);

#ifndef SW_CONTROLLED_CSMA

	/* 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();
	trx_reg_write(RG_CSMA_SEED_0, (uint8_t)rand_value);
	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();
#endif

	trx_bit_write(SR_AACK_SET_PD, SET_PD); /* ACKs for data requests,
	                                        * indicate pending data */
	trx_bit_write(SR_RX_SAFE_MODE, RX_SAFE_MODE_ENABLE); /* Enable
	                                                      * buffer
	                                                      * protection
	                                                      * mode */
	trx_bit_write(SR_IRQ_MASK_MODE, IRQ_MASK_MODE_ON); /* Enable poll
	                                                    * mode */
	trx_reg_write(RG_IRQ_MASK, TRX_IRQ_DEFAULT); /* The TRX_END
	                                              * interrupt of the
	                                              * transceiver is
	                                              * enabled. */

#if (ANTENNA_DIVERSITY == 1)
	trx_bit_write(SR_ANT_EXT_SW_EN, ANT_EXT_SW_ENABLE); /* Enable
	                                                     * antenna
	                                                     * diversity. */
#if (ANTENNA_DEFAULT != ANT_CTRL_1)
	trx_bit_write(SR_ANT_CTRL, ANTENNA_DEFAULT);
#endif  /* ANTENNA_DEFAULT */
#endif
#if ((defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP)) && \
	(DISABLE_TSTAMP_IRQ == 0)

	/*
	 * Use timestamping.
	 * The timestamping is only required for beaconing networks
	 * or if timestamping is explicitly enabled.
	 */
	/* Enable timestamping output signal - DIG2. */
	trx_bit_write(SR_IRQ_2_EXT_EN, RX_TIMESTAMPING_ENABLE);
#endif  /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */

#ifdef CCA_ED_THRESHOLD

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

#ifndef ENABLE_RX_OVERRIDE
	trx_bit_write(SR_RX_OVERRIDE, RXO_ENABLE);
#else

	/*
	 * Allow overriding of a 'weak' frame when another frame with stronger
	 * signal power arrives during the reception of this 'weak' frame.
	 */
	trx_bit_write(SR_RX_OVERRIDE, ENABLE_RX_OVERRIDE);
#endif /* ENABLE_RX_OVERRIDE */
}
Exemple #4
0
retval_t mlme_set(uint8_t attribute, pib_value_t *attribute_value,
		bool set_trx_to_sleep)
#endif
{
	/*
	 * Variables indicates whether the transceiver has been woken up for
	 * setting a TAL PIB attribute.
	 */
	static bool trx_pib_wakeup;

	retval_t status = MAC_SUCCESS;

	switch (attribute) {
#if (MAC_ASSOCIATION_REQUEST_CONFIRM == 1)
	case macAssociatedPANCoord:
		mac_pib.mac_AssociatedPANCoord
			= attribute_value->pib_value_8bit;
		break;
#endif /* (MAC_ASSOCIATION_REQUEST_CONFIRM == 1) */

#if ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT))
	case macMaxFrameTotalWaitTime:
		mac_pib.mac_MaxFrameTotalWaitTime
			= attribute_value->pib_value_16bit;
		break;
#endif  /* ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT)) */

	case macResponseWaitTime:
		mac_pib.mac_ResponseWaitTime = attribute_value->pib_value_16bit;
		break;

	case macAutoRequest:
#if (MAC_BEACON_NOTIFY_INDICATION == 1)

		/*
		 * If the beacon notification indications are not included
		 * in the build, macAutoRequest can be changed as desired, since
		 * beacon frames will be indicated to the higher
		 * layer if required as defined by IEEE 802.15.4.
		 */
		mac_pib.mac_AutoRequest = attribute_value->pib_value_8bit;
		break;
#else

		/*
		 * If the beacon notification indications are not included
		 * in the build, macAutoRequest must not be changed, since
		 * beacon frames will never be indicated to the higher
		 * layer, i.e. the higher would not be able to act on
		 * received beacon frame information itself.
		 */
		status = MAC_INVALID_PARAMETER;
		break;
#endif  /* (MAC_BEACON_NOTIFY_INDICATION == 1) */

#ifdef GTS_SUPPORT
	case macGTSPermit:
		mac_pib.mac_GTSPermit
			= attribute_value->pib_value_8bit;
		break;
#endif /* GTS_SUPPORT */

	case macBattLifeExtPeriods:
		mac_pib.mac_BattLifeExtPeriods
			= attribute_value->pib_value_8bit;
		break;

#if (MAC_ASSOCIATION_INDICATION_RESPONSE == 1)
	case macAssociationPermit:
		mac_pib.mac_AssociationPermit = attribute_value->pib_value_8bit;
		break;
#endif /* (MAC_ASSOCIATION_INDICATION_RESPONSE == 1) */

#if (MAC_START_REQUEST_CONFIRM == 1)
	case macBeaconPayload:
		memcpy(mac_beacon_payload, attribute_value,
				mac_pib.mac_BeaconPayloadLength);
		break;

	case macBeaconPayloadLength:
#ifndef REDUCED_PARAM_CHECK

		/*
		 * If the application sits directly  on top of the MAC,
		 * this is also checked in mac_api.c.
		 */
		if (attribute_value->pib_value_8bit > aMaxBeaconPayloadLength) {
			status = MAC_INVALID_PARAMETER;
			break;
		}
#endif  /* REDUCED_PARAM_CHECK */
		mac_pib.mac_BeaconPayloadLength
			= attribute_value->pib_value_8bit;
		break;

	case macBSN:
		mac_pib.mac_BSN = attribute_value->pib_value_8bit;
		break;
#endif  /* (MAC_START_REQUEST_CONFIRM == 1) */

#if (MAC_INDIRECT_DATA_FFD == 1)
	case macTransactionPersistenceTime:
		mac_pib.mac_TransactionPersistenceTime
			= attribute_value->pib_value_16bit;
		break;
#endif /* (MAC_INDIRECT_DATA_FFD == 1) */
	case macCoordExtendedAddress:
		mac_pib.mac_CoordExtendedAddress
			= attribute_value->pib_value_64bit;
		break;

	case macCoordShortAddress:
		mac_pib.mac_CoordShortAddress
			= attribute_value->pib_value_16bit;
		break;

	case macDSN:
		mac_pib.mac_DSN = attribute_value->pib_value_8bit;
		break;

	case macRxOnWhenIdle:
		mac_pib.mac_RxOnWhenIdle = attribute_value->pib_value_8bit;
		/* Check whether radio state needs to change now, */
		if (mac_pib.mac_RxOnWhenIdle) {
			/* Check whether the radio needs to be woken up. */
			mac_trx_wakeup();

			/* Set transceiver in rx mode, otherwise it may stay in
			 * TRX_OFF). */
			tal_rx_enable(PHY_RX_ON);
		} else {
			/* Check whether the radio needs to be put to sleep. */
			mac_sleep_trans();
		}

		break;

	case macBattLifeExt:
	case macBeaconOrder:
	case macMaxCSMABackoffs:
	case macMaxBE:
	case macMaxFrameRetries:
	case macMinBE:
	case macPANId:
#ifdef PROMISCUOUS_MODE
	case macPromiscuousMode:
#endif /* PROMISCUOUS_MODE */
	case macShortAddress:
	case macSuperframeOrder:
	case macIeeeAddress:
	case phyCurrentChannel:
	case phyCurrentPage:
	case phyTransmitPower:
	case phyCCAMode:
#ifdef TEST_HARNESS
	case macPrivateCCAFailure:
	case macPrivateDisableACK:
#endif /* TEST_HARNESS */
		{
			/* Now only TAL PIB attributes are handled anymore. */
			status = tal_pib_set(attribute, attribute_value);

			if (status == TAL_TRX_ASLEEP) {
				/*
				 * Wake up the transceiver and repeat the
				 * attempt
				 * to set the TAL PIB attribute.
				 */
				tal_trx_wakeup();
				status
					= tal_pib_set(attribute,
						attribute_value);
				if (status == MAC_SUCCESS) {
					/*
					 * Set flag indicating that the trx has
					 * been woken up
					 * during PIB setting.
					 */
					trx_pib_wakeup = true;
				}
			}

#if ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT))

			/*
			 * In any case that the PIB setting was successful (no
			 * matter
			 * whether the trx had to be woken up or not), the PIB
			 * attribute
			 * recalculation needs to be done.
			 */
			if (status == MAC_SUCCESS) {
				/*
				 * The value of the PIB attribute
				 * macMaxFrameTotalWaitTime depends on the
				 * values of the
				 * following PIB attributes:
				 * macMinBE
				 * macMaxBE
				 * macMaxCSMABackoffs
				 * phyMaxFrameDuration
				 * In order to save code space and since
				 * changing of PIB
				 * attributes is going to happen not too often,
				 * this is done
				 * always whenever a PIB attribute residing in
				 * TAL is changed
				 * (since all above mentioned PIB attributes are
				 * in TAL).
				 */
				recalc_macMaxFrameTotalWaitTime();
			}
#endif  /* ((MAC_INDIRECT_DATA_BASIC == 1) || defined(BEACON_SUPPORT)) */
		}
		break;

	case macAckWaitDuration:
	default:
		status = MAC_UNSUPPORTED_ATTRIBUTE;
		break;

#if ((defined MAC_SECURITY_ZIP)  || (defined MAC_SECURITY_2006))
	case macSecurityEnabled:
		mac_pib.mac_SecurityEnabled = attribute_value->pib_value_8bit;
		break;

	case macKeyTable:
		if (attribute_index >= mac_sec_pib.KeyTableEntries) {
			status = MAC_INVALID_INDEX;
		} else {
			memcpy(&mac_sec_pib.KeyTable[attribute_index],
					attribute_value,
					sizeof(mac_key_table_t));
		}

		break;

	case macKeyTableEntries:
		if (attribute_value->pib_value_8bit >
				MAC_ZIP_MAX_KEY_TABLE_ENTRIES) {
			status = MAC_INVALID_PARAMETER;
		} else {
			mac_sec_pib.KeyTableEntries
				= attribute_value->pib_value_8bit;
		}

		break;

	case macDeviceTable:
		if (attribute_index >= mac_sec_pib.DeviceTableEntries) {
			status = MAC_INVALID_INDEX;
		} else {
			uint8_t *attribute_temp_ptr
				= (uint8_t *)attribute_value;

			/*
			 * Since the members of the mac_dev_table_t structure do
			 * contain padding bytes,
			 * each member needs to be filled in separately.
			 */
			/* PAN-Id */
			memcpy((uint8_t *)&mac_sec_pib.DeviceTable[
						attribute_index].DeviceDescriptor[
						0].PANId,
					attribute_temp_ptr,
					sizeof(uint16_t));

			/*
			 *
			 *ADDR_COPY_DST_SRC_16(mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].PANId,
			 *(uint16_t *)attribute_temp_ptr); */
			attribute_temp_ptr += sizeof(uint16_t);

			/* Short Address */
			memcpy((uint8_t *)&mac_sec_pib.DeviceTable[
						attribute_index].DeviceDescriptor[
						0].ShortAddress,
					attribute_temp_ptr,
					sizeof(uint16_t));

			/*ADDR_COPY_DST_SRC_16(mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].ShortAddress,
			 *(uint16_t *)attribute_temp_ptr);*/
			attribute_temp_ptr += sizeof(uint16_t);

			/* Extended Address */
			memcpy((uint8_t *)&mac_sec_pib.DeviceTable[
						attribute_index].DeviceDescriptor[
						0].ExtAddress,
					attribute_temp_ptr,
					sizeof(uint64_t));

			/*ADDR_COPY_DST_SRC_64(mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[0].ExtAddress,
			 *(uint64_t *)attribute_temp_ptr);*/
			attribute_temp_ptr += sizeof(uint64_t);

			/* Extended Address */
			memcpy(
					&mac_sec_pib.DeviceTable[attribute_index].DeviceDescriptor[
						0].FrameCounter,
					attribute_temp_ptr,
					sizeof(uint32_t));
			attribute_temp_ptr += sizeof(uint32_t);

			/* Exempt */
			mac_sec_pib.DeviceTable[attribute_index].
			DeviceDescriptor[0].Exempt
				= *attribute_temp_ptr;
		}

		break;

	case macDeviceTableEntries:
		if (attribute_value->pib_value_16bit >
				MAC_ZIP_MAX_DEV_TABLE_ENTRIES) {
			status = MAC_INVALID_PARAMETER;
		} else {
			mac_sec_pib.DeviceTableEntries
				= attribute_value->pib_value_16bit;
		}

		break;

	case macSecurityLevelTable:
		if (attribute_index >= mac_sec_pib.SecurityLevelTableEntries) {
			status = MAC_INVALID_INDEX;
		} else {
			memcpy(&mac_sec_pib.SecurityLevelTable[attribute_index],
					attribute_value,
					sizeof(mac_sec_lvl_table_t));
		}

		break;

	case macSecurityLevelTableEntries:
		if (attribute_value->pib_value_8bit >
				MAC_ZIP_MAX_SEC_LVL_TABLE_ENTRIES) {
			status = MAC_INVALID_PARAMETER;
		} else {
			mac_sec_pib.SecurityLevelTableEntries
				= attribute_value->pib_value_8bit;
		}

		break;

	case macFrameCounter:
		mac_sec_pib.FrameCounter = attribute_value->pib_value_32bit;
		break;

	case macDefaultKeySource:
		/* Key Source length is 8 octets. */
		memcpy(mac_sec_pib.DefaultKeySource, attribute_value, 8);
		break;

	case macPANCoordExtendedAddress:
		memcpy(mac_sec_pib.PANCoordExtendedAddress, attribute_value, 8);
		break;

	case macPANCoordShortAddress:
		mac_sec_pib.PANCoordShortAddress
			= attribute_value->pib_value_16bit;
		break;
#endif  /* (MAC_SECURITY_ZIP || MAC_SECURITY_2006) */

#ifdef TEST_HARNESS
	case macPrivateIllegalFrameType:
		mac_pib.privateIllegalFrameType
			= attribute_value->pib_value_8bit;
		break;

	case macPrivateNoDataAfterAssocReq:
		mac_pib.privateNoDataAfterAssocReq
			= attribute_value->pib_value_8bit;
		break;

	case macPrivateVirtualPANs:
		mac_pib.privateVirtualPANs = attribute_value->pib_value_8bit;
		break;
#endif /* TEST_HARNESS */
	}

	/*
	 * In case the transceiver shall be forced back to sleep and
	 * has been woken up, it is put back to sleep again.
	 */
	if (set_trx_to_sleep && trx_pib_wakeup && !mac_pib.mac_RxOnWhenIdle) {
#ifdef ENABLE_DEEP_SLEEP
		tal_trx_sleep(DEEP_SLEEP_MODE);
#else
		tal_trx_sleep(SLEEP_MODE_1);
#endif
		trx_pib_wakeup = false;
	}

	return status;
}