/** * @brief Resets TAL state machine and sets the default PIB values if requested * * @param set_default_pib Defines whether PIB values need to be set * to its default values * * @return MAC_SUCCESS if the transceiver state is changed to TRX_OFF * FAILURE otherwise */ retval_t tal_reset(bool set_default_pib) { /* * Do the reset stuff. * Set the default PIBs depending on the given parameter set_default_pib. * Do NOT generate random seed again. */ if (internal_tal_reset(set_default_pib) != MAC_SUCCESS) { return FAILURE; } #if (NUMBER_OF_TAL_TIMERS > 0) /* Clear all running TAL timers. */ { uint8_t timer_id; ENTER_CRITICAL_REGION(); for (timer_id = TAL_FIRST_TIMER_ID; timer_id <= TAL_LAST_TIMER_ID; timer_id++) { pal_timer_stop(timer_id); } LEAVE_CRITICAL_REGION(); } #endif /* Clear TAL Incoming Frame queue and free used buffers. */ while (tal_incoming_frame_queue.size > 0) { buffer_t *frame = qmm_queue_remove(&tal_incoming_frame_queue, NULL); if (NULL != frame) { bmm_buffer_free(frame); } } #ifdef ENABLE_TFA tfa_reset(set_default_pib); #endif /* * Configure interrupt handling. Clear all pending interrupts. * Handlers have been installed in tal_init(), and are never * uninstalled. */ pal_trx_irq_flag_clr_rx_end(); pal_trx_irq_flag_clr_tx_end(); #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) pal_trx_irq_flag_clr_tstamp(); #endif /* (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */ pal_trx_irq_flag_clr_awake(); /* * To make sure that the CSMA seed is properly set within the transceiver, * put the trx to sleep briefly and wake it up again. */ tal_trx_sleep(SLEEP_MODE_1); tal_trx_wakeup(); #ifdef ENABLE_FTN_PLL_CALIBRATION { /* Handle PLL calibration and filter tuning. */ retval_t timer_status; /* Calibration timer has already been stopped within this function. */ /* Start periodic calibration timer.*/ timer_status = pal_timer_start(TAL_CALIBRATION, TAL_CALIBRATION_TIMEOUT_US, TIMEOUT_RELATIVE, (FUNC_PTR)calibration_timer_handler_cb, NULL); if (timer_status != MAC_SUCCESS) { ASSERT("PLL calibration timer start problem" == 0); } } #endif /* ENABLE_FTN_PLL_CALIBRATION */ #ifdef STB_ON_SAL stb_restart(); #endif return MAC_SUCCESS; }
/** * \brief 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 */ }
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; }