| /** |
| **************************************************************************************** |
| * |
| * @file common.c |
| * |
| * @brief Common FTDF functions |
| * |
| * Copyright (c) 2016, Dialog Semiconductor |
| * All rights reserved. |
| * Redistribution and use in source and binary forms, with or without modification, |
| * are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the names of its contributors |
| * may be used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, |
| * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
| * OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * |
| **************************************************************************************** |
| */ |
| |
| #include <string.h> |
| #include <stdlib.h> |
| |
| #include <ftdf.h> |
| #include "internal.h" |
| #include "regmap.h" |
| #include "sdk_defs.h" |
| |
| #if dg_configCOEX_ENABLE_CONFIG |
| #include "hw_coex.h" |
| #endif |
| typedef struct |
| { |
| void *addr; |
| uint8_t size; |
| void (* getFunc)(void); |
| void (* setFunc)(void); |
| } PIBAttributeDef; |
| |
| typedef struct |
| { |
| PIBAttributeDef attributeDefs[ FTDF_NR_OF_PIB_ATTRIBUTES + 1 ]; |
| } PIBAttributeTable; |
| |
| struct FTDF_Pib FTDF_pib __attribute__((section(".retention"))); |
| |
| #if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO |
| #if FTDF_FPPR_DEFER_INVALIDATION |
| static struct |
| { |
| FTDF_AddressMode addrMode; |
| FTDF_PANId PANId; |
| FTDF_Address addr; |
| } FTDF_fpprPending __attribute__((section(".retention"))); |
| #endif /* FTDF_FPPR_DEFER_INVALIDATION */ |
| #endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */ |
| |
| #ifndef FTDF_LITE |
| const FTDF_ChannelNumber page0Channels[ FTDF_NR_OF_CHANNELS ] = |
| { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; |
| const FTDF_ChannelDescriptor channelDescriptors[ 1 ] = { { 0, 16, (FTDF_ChannelNumber *) page0Channels } }; |
| const FTDF_ChannelDescriptorList channelsSupported = { 1, (FTDF_ChannelDescriptor *) channelDescriptors }; |
| #endif |
| |
| const PIBAttributeTable pibAttributeTable = |
| { |
| .attributeDefs[ FTDF_PIB_EXTENDED_ADDRESS ].addr = &FTDF_pib.extAddress, |
| .attributeDefs[ FTDF_PIB_EXTENDED_ADDRESS ].size = sizeof(FTDF_pib.extAddress), |
| .attributeDefs[ FTDF_PIB_EXTENDED_ADDRESS ].getFunc = FTDF_getExtAddress, |
| .attributeDefs[ FTDF_PIB_EXTENDED_ADDRESS ].setFunc = FTDF_setExtAddress, |
| .attributeDefs[ FTDF_PIB_ACK_WAIT_DURATION ].addr = &FTDF_pib.ackWaitDuration, |
| .attributeDefs[ FTDF_PIB_ACK_WAIT_DURATION ].size = 0, |
| .attributeDefs[ FTDF_PIB_ACK_WAIT_DURATION ].getFunc = FTDF_getAckWaitDuration, |
| .attributeDefs[ FTDF_PIB_ACK_WAIT_DURATION ].setFunc = NULL, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_ASSOCIATION_PAN_COORD ].addr = &FTDF_pib.associatedPANCoord, |
| .attributeDefs[ FTDF_PIB_ASSOCIATION_PAN_COORD ].size = sizeof(FTDF_pib.associatedPANCoord), |
| .attributeDefs[ FTDF_PIB_ASSOCIATION_PAN_COORD ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_ASSOCIATION_PAN_COORD ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_ASSOCIATION_PERMIT ].addr = &FTDF_pib.associationPermit, |
| .attributeDefs[ FTDF_PIB_ASSOCIATION_PERMIT ].size = sizeof(FTDF_pib.associationPermit), |
| .attributeDefs[ FTDF_PIB_ASSOCIATION_PERMIT ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_ASSOCIATION_PERMIT ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_AUTO_REQUEST ].addr = &FTDF_pib.autoRequest, |
| .attributeDefs[ FTDF_PIB_AUTO_REQUEST ].size = sizeof(FTDF_pib.autoRequest), |
| .attributeDefs[ FTDF_PIB_AUTO_REQUEST ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_AUTO_REQUEST ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BATT_LIFE_EXT ].addr = &FTDF_pib.battLifeExt, |
| .attributeDefs[ FTDF_PIB_BATT_LIFE_EXT ].size = sizeof(FTDF_pib.battLifeExt), |
| .attributeDefs[ FTDF_PIB_BATT_LIFE_EXT ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BATT_LIFE_EXT ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BATT_LIFE_EXT_PERIODS ].addr = &FTDF_pib.battLifeExtPeriods, |
| .attributeDefs[ FTDF_PIB_BATT_LIFE_EXT_PERIODS ].size = sizeof(FTDF_pib.battLifeExtPeriods), |
| .attributeDefs[ FTDF_PIB_BATT_LIFE_EXT_PERIODS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BATT_LIFE_EXT_PERIODS ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_PAYLOAD ].addr = &FTDF_pib.beaconPayload, |
| .attributeDefs[ FTDF_PIB_BEACON_PAYLOAD ].size = sizeof(FTDF_pib.beaconPayload), |
| .attributeDefs[ FTDF_PIB_BEACON_PAYLOAD ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_PAYLOAD ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_PAYLOAD_LENGTH ].addr = &FTDF_pib.beaconPayloadLength, |
| .attributeDefs[ FTDF_PIB_BEACON_PAYLOAD_LENGTH ].size = sizeof(FTDF_pib.beaconPayloadLength), |
| .attributeDefs[ FTDF_PIB_BEACON_PAYLOAD_LENGTH ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_PAYLOAD_LENGTH ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_ORDER ].addr = &FTDF_pib.beaconOrder, |
| .attributeDefs[ FTDF_PIB_BEACON_ORDER ].size = 0, |
| .attributeDefs[ FTDF_PIB_BEACON_ORDER ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_ORDER ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_TX_TIME ].addr = &FTDF_pib.beaconTxTime, |
| .attributeDefs[ FTDF_PIB_BEACON_TX_TIME ].size = sizeof(FTDF_pib.beaconTxTime), |
| .attributeDefs[ FTDF_PIB_BEACON_TX_TIME ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_TX_TIME ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BSN ].addr = &FTDF_pib.BSN, |
| .attributeDefs[ FTDF_PIB_BSN ].size = sizeof(FTDF_pib.BSN), |
| .attributeDefs[ FTDF_PIB_BSN ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BSN ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_COORD_EXTENDED_ADDRESS ].addr = &FTDF_pib.coordExtAddress, |
| .attributeDefs[ FTDF_PIB_COORD_EXTENDED_ADDRESS ].size = sizeof(FTDF_pib.coordExtAddress), |
| .attributeDefs[ FTDF_PIB_COORD_EXTENDED_ADDRESS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_COORD_EXTENDED_ADDRESS ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_COORD_SHORT_ADDRESS ].addr = &FTDF_pib.coordShortAddress, |
| .attributeDefs[ FTDF_PIB_COORD_SHORT_ADDRESS ].size = sizeof(FTDF_pib.coordShortAddress), |
| .attributeDefs[ FTDF_PIB_COORD_SHORT_ADDRESS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_COORD_SHORT_ADDRESS ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DSN ].addr = &FTDF_pib.DSN, |
| .attributeDefs[ FTDF_PIB_DSN ].size = sizeof(FTDF_pib.DSN), |
| .attributeDefs[ FTDF_PIB_DSN ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DSN ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_GTS_PERMIT ].addr = &FTDF_pib.GTSPermit, |
| .attributeDefs[ FTDF_PIB_GTS_PERMIT ].size = 0, |
| .attributeDefs[ FTDF_PIB_GTS_PERMIT ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_GTS_PERMIT ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_MAX_BE ].addr = &FTDF_pib.maxBE, |
| .attributeDefs[ FTDF_PIB_MAX_BE ].size = sizeof(FTDF_pib.maxBE), |
| .attributeDefs[ FTDF_PIB_MAX_BE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MAX_BE ].setFunc = FTDF_setMaxBE, |
| .attributeDefs[ FTDF_PIB_MAX_CSMA_BACKOFFS ].addr = &FTDF_pib.maxCSMABackoffs, |
| .attributeDefs[ FTDF_PIB_MAX_CSMA_BACKOFFS ].size = sizeof(FTDF_pib.maxCSMABackoffs), |
| .attributeDefs[ FTDF_PIB_MAX_CSMA_BACKOFFS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MAX_CSMA_BACKOFFS ].setFunc = FTDF_setMaxCSMABackoffs, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_TOTAL_WAIT_TIME ].addr = &FTDF_pib.maxFrameTotalWaitTime, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_TOTAL_WAIT_TIME ].size = sizeof(FTDF_pib.maxFrameTotalWaitTime), |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_TOTAL_WAIT_TIME ].getFunc = FTDF_getMaxFrameTotalWaitTime, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_TOTAL_WAIT_TIME ].setFunc = FTDF_setMaxFrameTotalWaitTime, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_RETRIES ].addr = &FTDF_pib.maxFrameRetries, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_RETRIES ].size = sizeof(FTDF_pib.maxFrameRetries), |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_RETRIES ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_RETRIES ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MIN_BE ].addr = &FTDF_pib.minBE, |
| .attributeDefs[ FTDF_PIB_MIN_BE ].size = sizeof(FTDF_pib.minBE), |
| .attributeDefs[ FTDF_PIB_MIN_BE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MIN_BE ].setFunc = FTDF_setMinBE, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_LIFS_PERIOD ].addr = &FTDF_pib.LIFSPeriod, |
| .attributeDefs[ FTDF_PIB_LIFS_PERIOD ].size = 0, |
| .attributeDefs[ FTDF_PIB_LIFS_PERIOD ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LIFS_PERIOD ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SIFS_PERIOD ].addr = &FTDF_pib.SIFSPeriod, |
| .attributeDefs[ FTDF_PIB_SIFS_PERIOD ].size = 0, |
| .attributeDefs[ FTDF_PIB_SIFS_PERIOD ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SIFS_PERIOD ].setFunc = NULL, |
| #endif |
| .attributeDefs[ FTDF_PIB_PAN_ID ].addr = &FTDF_pib.PANId, |
| .attributeDefs[ FTDF_PIB_PAN_ID ].size = sizeof(FTDF_pib.PANId), |
| .attributeDefs[ FTDF_PIB_PAN_ID ].getFunc = FTDF_getPANId, |
| .attributeDefs[ FTDF_PIB_PAN_ID ].setFunc = FTDF_setPANId, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_PROMISCUOUS_MODE ].addr = &FTDF_pib.promiscuousMode, |
| .attributeDefs[ FTDF_PIB_PROMISCUOUS_MODE ].size = sizeof(FTDF_pib.promiscuousMode), |
| .attributeDefs[ FTDF_PIB_PROMISCUOUS_MODE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_PROMISCUOUS_MODE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_RESPONSE_WAIT_TIME ].addr = &FTDF_pib.responseWaitTime, |
| .attributeDefs[ FTDF_PIB_RESPONSE_WAIT_TIME ].size = sizeof(FTDF_pib.responseWaitTime), |
| .attributeDefs[ FTDF_PIB_RESPONSE_WAIT_TIME ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_RESPONSE_WAIT_TIME ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_RX_ON_WHEN_IDLE ].addr = &FTDF_pib.rxOnWhenIdle, |
| .attributeDefs[ FTDF_PIB_RX_ON_WHEN_IDLE ].size = sizeof(FTDF_pib.rxOnWhenIdle), |
| .attributeDefs[ FTDF_PIB_RX_ON_WHEN_IDLE ].getFunc = FTDF_getRxOnWhenIdle, |
| .attributeDefs[ FTDF_PIB_RX_ON_WHEN_IDLE ].setFunc = FTDF_setRxOnWhenIdle, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_SECURITY_ENABLED ].addr = &FTDF_pib.securityEnabled, |
| .attributeDefs[ FTDF_PIB_SECURITY_ENABLED ].size = sizeof(FTDF_pib.securityEnabled), |
| .attributeDefs[ FTDF_PIB_SECURITY_ENABLED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SECURITY_ENABLED ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_SHORT_ADDRESS ].addr = &FTDF_pib.shortAddress, |
| .attributeDefs[ FTDF_PIB_SHORT_ADDRESS ].size = sizeof(FTDF_pib.shortAddress), |
| .attributeDefs[ FTDF_PIB_SHORT_ADDRESS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SHORT_ADDRESS ].setFunc = FTDF_setShortAddress, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_SUPERFRAME_ORDER ].addr = &FTDF_pib.superframeOrder, |
| .attributeDefs[ FTDF_PIB_SUPERFRAME_ORDER ].size = 0, |
| .attributeDefs[ FTDF_PIB_SUPERFRAME_ORDER ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SUPERFRAME_ORDER ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SYNC_SYMBOL_OFFSET ].addr = &FTDF_pib.syncSymbolOffset, |
| .attributeDefs[ FTDF_PIB_SYNC_SYMBOL_OFFSET ].size = 0, |
| .attributeDefs[ FTDF_PIB_SYNC_SYMBOL_OFFSET ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SYNC_SYMBOL_OFFSET ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TIMESTAMP_SUPPORTED ].addr = &FTDF_pib.timestampSupported, |
| .attributeDefs[ FTDF_PIB_TIMESTAMP_SUPPORTED ].size = 0, |
| .attributeDefs[ FTDF_PIB_TIMESTAMP_SUPPORTED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TIMESTAMP_SUPPORTED ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TRANSACTION_PERSISTENCE_TIME ].addr = &FTDF_pib.transactionPersistenceTime, |
| .attributeDefs[ FTDF_PIB_TRANSACTION_PERSISTENCE_TIME ].size = |
| sizeof(FTDF_pib.transactionPersistenceTime), |
| .attributeDefs[ FTDF_PIB_TRANSACTION_PERSISTENCE_TIME ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TRANSACTION_PERSISTENCE_TIME ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_ENH_ACK_WAIT_DURATION ].addr = &FTDF_pib.enhAckWaitDuration, |
| .attributeDefs[ FTDF_PIB_ENH_ACK_WAIT_DURATION ].size = sizeof(FTDF_pib.enhAckWaitDuration), |
| .attributeDefs[ FTDF_PIB_ENH_ACK_WAIT_DURATION ].getFunc = FTDF_getEnhAckWaitDuration, |
| .attributeDefs[ FTDF_PIB_ENH_ACK_WAIT_DURATION ].setFunc = FTDF_setEnhAckWaitDuration, |
| .attributeDefs[ FTDF_PIB_IMPLICIT_BROADCAST ].addr = &FTDF_pib.implicitBroadcast, |
| .attributeDefs[ FTDF_PIB_IMPLICIT_BROADCAST ].size = sizeof(FTDF_pib.implicitBroadcast), |
| .attributeDefs[ FTDF_PIB_IMPLICIT_BROADCAST ].getFunc = FTDF_getImplicitBroadcast, |
| .attributeDefs[ FTDF_PIB_IMPLICIT_BROADCAST ].setFunc = FTDF_setImplicitBroadcast, |
| .attributeDefs[ FTDF_PIB_SIMPLE_ADDRESS ].addr = &FTDF_pib.simpleAddress, |
| .attributeDefs[ FTDF_PIB_SIMPLE_ADDRESS ].size = sizeof(FTDF_pib.simpleAddress), |
| .attributeDefs[ FTDF_PIB_SIMPLE_ADDRESS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SIMPLE_ADDRESS ].setFunc = FTDF_setSimpleAddress, |
| .attributeDefs[ FTDF_PIB_DISCONNECT_TIME ].addr = &FTDF_pib.disconnectTime, |
| .attributeDefs[ FTDF_PIB_DISCONNECT_TIME ].size = sizeof(FTDF_pib.disconnectTime), |
| .attributeDefs[ FTDF_PIB_DISCONNECT_TIME ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DISCONNECT_TIME ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_JOIN_PRIORITY ].addr = &FTDF_pib.joinPriority, |
| .attributeDefs[ FTDF_PIB_JOIN_PRIORITY ].size = sizeof(FTDF_pib.joinPriority), |
| .attributeDefs[ FTDF_PIB_JOIN_PRIORITY ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_JOIN_PRIORITY ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_ASN ].addr = &FTDF_pib.ASN, |
| .attributeDefs[ FTDF_PIB_ASN ].size = sizeof(FTDF_pib.ASN), |
| .attributeDefs[ FTDF_PIB_ASN ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_ASN ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_NO_HL_BUFFERS ].addr = &FTDF_pib.noHLBuffers, |
| .attributeDefs[ FTDF_PIB_NO_HL_BUFFERS ].size = sizeof(FTDF_pib.noHLBuffers), |
| .attributeDefs[ FTDF_PIB_NO_HL_BUFFERS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_NO_HL_BUFFERS ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SLOTFRAME_TABLE ].addr = &FTDF_pib.slotframeTable, |
| .attributeDefs[ FTDF_PIB_SLOTFRAME_TABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_SLOTFRAME_TABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SLOTFRAME_TABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LINK_TABLE ].addr = &FTDF_pib.linkTable, |
| .attributeDefs[ FTDF_PIB_LINK_TABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_LINK_TABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LINK_TABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TIMESLOT_TEMPLATE ].addr = &FTDF_pib.timeslotTemplate, |
| .attributeDefs[ FTDF_PIB_TIMESLOT_TEMPLATE ].size = sizeof(FTDF_pib.timeslotTemplate), |
| .attributeDefs[ FTDF_PIB_TIMESLOT_TEMPLATE ].getFunc = NULL, |
| #ifdef FTDF_NO_TSCH |
| .attributeDefs[ FTDF_PIB_TIMESLOT_TEMPLATE ].setFunc = NULL, |
| #else |
| .attributeDefs[ FTDF_PIB_TIMESLOT_TEMPLATE ].setFunc = FTDF_setTimeslotTemplate, |
| #endif /* FTDF_NO_TSCH */ |
| .attributeDefs[ FTDF_PIB_HOPPINGSEQUENCE_ID ].addr = &FTDF_pib.HoppingSequenceId, |
| .attributeDefs[ FTDF_PIB_HOPPINGSEQUENCE_ID ].size = sizeof(FTDF_pib.HoppingSequenceId), |
| .attributeDefs[ FTDF_PIB_HOPPINGSEQUENCE_ID ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_HOPPINGSEQUENCE_ID ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CHANNEL_PAGE ].addr = &FTDF_pib.channelPage, |
| .attributeDefs[ FTDF_PIB_CHANNEL_PAGE ].size = sizeof(FTDF_pib.channelPage), |
| .attributeDefs[ FTDF_PIB_CHANNEL_PAGE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CHANNEL_PAGE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_NUMBER_OF_CHANNELS ].addr = &FTDF_pib.numberOfChannels, |
| .attributeDefs[ FTDF_PIB_NUMBER_OF_CHANNELS ].size = sizeof(FTDF_pib.numberOfChannels), |
| .attributeDefs[ FTDF_PIB_NUMBER_OF_CHANNELS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_NUMBER_OF_CHANNELS ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_PHY_CONFIGURATION ].addr = &FTDF_pib.phyConfiguration, |
| .attributeDefs[ FTDF_PIB_PHY_CONFIGURATION ].size = sizeof(FTDF_pib.phyConfiguration), |
| .attributeDefs[ FTDF_PIB_PHY_CONFIGURATION ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_PHY_CONFIGURATION ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EXTENTED_BITMAP ].addr = &FTDF_pib.extendedBitmap, |
| .attributeDefs[ FTDF_PIB_EXTENTED_BITMAP ].size = sizeof(FTDF_pib.extendedBitmap), |
| .attributeDefs[ FTDF_PIB_EXTENTED_BITMAP ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EXTENTED_BITMAP ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_HOPPING_SEQUENCE_LENGTH ].addr = &FTDF_pib.hoppingSequenceLength, |
| .attributeDefs[ FTDF_PIB_HOPPING_SEQUENCE_LENGTH ].size = sizeof(FTDF_pib.hoppingSequenceLength), |
| .attributeDefs[ FTDF_PIB_HOPPING_SEQUENCE_LENGTH ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_HOPPING_SEQUENCE_LENGTH ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_HOPPING_SEQUENCE_LIST ].addr = FTDF_pib.hoppingSequenceList, |
| .attributeDefs[ FTDF_PIB_HOPPING_SEQUENCE_LIST ].size = sizeof(FTDF_pib.hoppingSequenceList), |
| .attributeDefs[ FTDF_PIB_HOPPING_SEQUENCE_LIST ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_HOPPING_SEQUENCE_LIST ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CURRENT_HOP ].addr = &FTDF_pib.currentHop, |
| .attributeDefs[ FTDF_PIB_CURRENT_HOP ].size = sizeof(FTDF_pib.currentHop), |
| .attributeDefs[ FTDF_PIB_CURRENT_HOP ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CURRENT_HOP ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DWELL_TIME ].addr = &FTDF_pib.dwellTime, |
| .attributeDefs[ FTDF_PIB_DWELL_TIME ].size = sizeof(FTDF_pib.dwellTime), |
| .attributeDefs[ FTDF_PIB_DWELL_TIME ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DWELL_TIME ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_PERIOD ].addr = &FTDF_pib.CSLPeriod, |
| .attributeDefs[ FTDF_PIB_CSL_PERIOD ].size = sizeof(FTDF_pib.CSLPeriod), |
| .attributeDefs[ FTDF_PIB_CSL_PERIOD ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_PERIOD ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_MAX_PERIOD ].addr = &FTDF_pib.CSLMaxPeriod, |
| .attributeDefs[ FTDF_PIB_CSL_MAX_PERIOD ].size = sizeof(FTDF_pib.CSLMaxPeriod), |
| .attributeDefs[ FTDF_PIB_CSL_MAX_PERIOD ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_MAX_PERIOD ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_CHANNEL_MASK ].addr = &FTDF_pib.CSLChannelMask, |
| .attributeDefs[ FTDF_PIB_CSL_CHANNEL_MASK ].size = sizeof(FTDF_pib.CSLChannelMask), |
| .attributeDefs[ FTDF_PIB_CSL_CHANNEL_MASK ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_CHANNEL_MASK ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_FRAME_PENDING_WAIT_T ].addr = &FTDF_pib.CSLFramePendingWaitT, |
| .attributeDefs[ FTDF_PIB_CSL_FRAME_PENDING_WAIT_T ].size = sizeof(FTDF_pib.CSLFramePendingWaitT), |
| #ifdef FTDF_NO_CSL |
| .attributeDefs[ FTDF_PIB_CSL_FRAME_PENDING_WAIT_T ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_FRAME_PENDING_WAIT_T ].setFunc = NULL, |
| #else |
| .attributeDefs[ FTDF_PIB_CSL_FRAME_PENDING_WAIT_T ].getFunc = FTDF_getCslFramePendingWaitT, |
| .attributeDefs[ FTDF_PIB_CSL_FRAME_PENDING_WAIT_T ].setFunc = FTDF_setCslFramePendingWaitT, |
| #endif /* FTDF_NO_CSL */ |
| .attributeDefs[ FTDF_PIB_LOW_ENERGY_SUPERFRAME_SUPPORTED ].addr = &FTDF_pib.lowEnergySuperframeSupported, |
| .attributeDefs[ FTDF_PIB_LOW_ENERGY_SUPERFRAME_SUPPORTED ].size = |
| sizeof(FTDF_pib.lowEnergySuperframeSupported), |
| .attributeDefs[ FTDF_PIB_LOW_ENERGY_SUPERFRAME_SUPPORTED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LOW_ENERGY_SUPERFRAME_SUPPORTED ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LOW_ENERGY_SUPERFRAME_SYNC_INTERVAL ].addr = &FTDF_pib.lowEnergySuperframeSyncInterval, |
| .attributeDefs[ FTDF_PIB_LOW_ENERGY_SUPERFRAME_SYNC_INTERVAL ].size = |
| sizeof(FTDF_pib.lowEnergySuperframeSyncInterval), |
| .attributeDefs[ FTDF_PIB_LOW_ENERGY_SUPERFRAME_SYNC_INTERVAL ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LOW_ENERGY_SUPERFRAME_SYNC_INTERVAL ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_PERFORMANCE_METRICS ].addr = &FTDF_pib.performanceMetrics, |
| .attributeDefs[ FTDF_PIB_PERFORMANCE_METRICS ].size = sizeof(FTDF_pib.performanceMetrics), |
| .attributeDefs[ FTDF_PIB_PERFORMANCE_METRICS ].getFunc = FTDF_getLmacPmData, |
| .attributeDefs[ FTDF_PIB_PERFORMANCE_METRICS ].setFunc = NULL, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_USE_ENHANCED_BEACON ].addr = &FTDF_pib.useEnhancedBecaon, |
| .attributeDefs[ FTDF_PIB_USE_ENHANCED_BEACON ].size = sizeof(FTDF_pib.useEnhancedBecaon), |
| .attributeDefs[ FTDF_PIB_USE_ENHANCED_BEACON ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_USE_ENHANCED_BEACON ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EB_IE_LIST ].addr = &FTDF_pib.EBIEList, |
| .attributeDefs[ FTDF_PIB_EB_IE_LIST ].size = sizeof(FTDF_pib.EBIEList), |
| .attributeDefs[ FTDF_PIB_EB_IE_LIST ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EB_IE_LIST ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EB_FILTERING_ENABLED ].addr = &FTDF_pib.EBFilteringEnabled, |
| .attributeDefs[ FTDF_PIB_EB_FILTERING_ENABLED ].size = sizeof(FTDF_pib.EBFilteringEnabled), |
| .attributeDefs[ FTDF_PIB_EB_FILTERING_ENABLED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EB_FILTERING_ENABLED ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EBSN ].addr = &FTDF_pib.EBSN, |
| .attributeDefs[ FTDF_PIB_EBSN ].size = sizeof(FTDF_pib.EBSN), |
| .attributeDefs[ FTDF_PIB_EBSN ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EBSN ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EB_AUTO_SA ].addr = &FTDF_pib.EBAutoSA, |
| .attributeDefs[ FTDF_PIB_EB_AUTO_SA ].size = sizeof(FTDF_pib.EBAutoSA), |
| .attributeDefs[ FTDF_PIB_EB_AUTO_SA ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EB_AUTO_SA ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EACK_IE_LIST ].addr = &FTDF_pib.EAckIEList, |
| .attributeDefs[ FTDF_PIB_EACK_IE_LIST ].size = sizeof(FTDF_pib.EAckIEList), |
| .attributeDefs[ FTDF_PIB_EACK_IE_LIST ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_EACK_IE_LIST ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_KEY_TABLE ].addr = &FTDF_pib.keyTable, |
| .attributeDefs[ FTDF_PIB_KEY_TABLE ].size = sizeof(FTDF_pib.keyTable), |
| .attributeDefs[ FTDF_PIB_KEY_TABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_KEY_TABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DEVICE_TABLE ].addr = &FTDF_pib.deviceTable, |
| .attributeDefs[ FTDF_PIB_DEVICE_TABLE ].size = sizeof(FTDF_pib.deviceTable), |
| .attributeDefs[ FTDF_PIB_DEVICE_TABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DEVICE_TABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SECURITY_LEVEL_TABLE ].addr = &FTDF_pib.securityLevelTable, |
| .attributeDefs[ FTDF_PIB_SECURITY_LEVEL_TABLE ].size = sizeof(FTDF_pib.securityLevelTable), |
| .attributeDefs[ FTDF_PIB_SECURITY_LEVEL_TABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SECURITY_LEVEL_TABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_FRAME_COUNTER ].addr = &FTDF_pib.frameCounter, |
| .attributeDefs[ FTDF_PIB_FRAME_COUNTER ].size = sizeof(FTDF_pib.frameCounter), |
| .attributeDefs[ FTDF_PIB_FRAME_COUNTER ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_FRAME_COUNTER ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MT_DATA_SECURITY_LEVEL ].addr = &FTDF_pib.mtDataSecurityLevel, |
| .attributeDefs[ FTDF_PIB_MT_DATA_SECURITY_LEVEL ].size = |
| sizeof(FTDF_pib.mtDataSecurityLevel), |
| .attributeDefs[ FTDF_PIB_MT_DATA_SECURITY_LEVEL ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MT_DATA_SECURITY_LEVEL ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_ID_MODE ].addr = &FTDF_pib.mtDataKeyIdMode, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_ID_MODE ].size = sizeof(FTDF_pib.mtDataKeyIdMode), |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_ID_MODE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_ID_MODE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_SOURCE ].addr = &FTDF_pib.mtDataKeySource, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_SOURCE ].size = sizeof(FTDF_pib.mtDataKeySource), |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_SOURCE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_SOURCE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_INDEX ].addr = &FTDF_pib.mtDataKeyIndex, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_INDEX ].size = sizeof(FTDF_pib.mtDataKeyIndex), |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_INDEX ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MT_DATA_KEY_INDEX ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DEFAULT_KEY_SOURCE ].addr = &FTDF_pib.defaultKeySource, |
| .attributeDefs[ FTDF_PIB_DEFAULT_KEY_SOURCE ].size = sizeof(FTDF_pib.defaultKeySource), |
| .attributeDefs[ FTDF_PIB_DEFAULT_KEY_SOURCE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DEFAULT_KEY_SOURCE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_PAN_COORD_EXTENDED_ADDRESS ].addr = &FTDF_pib.PANCoordExtAddress, |
| .attributeDefs[ FTDF_PIB_PAN_COORD_EXTENDED_ADDRESS ].size = sizeof(FTDF_pib.PANCoordExtAddress), |
| .attributeDefs[ FTDF_PIB_PAN_COORD_EXTENDED_ADDRESS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_PAN_COORD_EXTENDED_ADDRESS ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_PAN_COORD_SHORT_ADDRESS ].addr = &FTDF_pib.PANCoordShortAddress, |
| .attributeDefs[ FTDF_PIB_PAN_COORD_SHORT_ADDRESS ].size = sizeof(FTDF_pib.PANCoordShortAddress), |
| .attributeDefs[ FTDF_PIB_PAN_COORD_SHORT_ADDRESS ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_PAN_COORD_SHORT_ADDRESS ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_FRAME_COUNTER_MODE ].addr = &FTDF_pib.frameCounterMode, |
| .attributeDefs[ FTDF_PIB_FRAME_COUNTER_MODE ].size = sizeof(FTDF_pib.frameCounterMode), |
| .attributeDefs[ FTDF_PIB_FRAME_COUNTER_MODE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_FRAME_COUNTER_MODE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_SYNC_TX_MARGIN ].addr = &FTDF_pib.CSLSyncTxMargin, |
| .attributeDefs[ FTDF_PIB_CSL_SYNC_TX_MARGIN ].size = sizeof(FTDF_pib.CSLSyncTxMargin), |
| .attributeDefs[ FTDF_PIB_CSL_SYNC_TX_MARGIN ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_SYNC_TX_MARGIN ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_MAX_AGE_REMOTE_INFO ].addr = &FTDF_pib.CSLMaxAgeRemoteInfo, |
| .attributeDefs[ FTDF_PIB_CSL_MAX_AGE_REMOTE_INFO ].size = sizeof(FTDF_pib.CSLMaxAgeRemoteInfo), |
| .attributeDefs[ FTDF_PIB_CSL_MAX_AGE_REMOTE_INFO ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CSL_MAX_AGE_REMOTE_INFO ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TSCH_ENABLED ].addr = &FTDF_pib.tschEnabled, |
| .attributeDefs[ FTDF_PIB_TSCH_ENABLED ].size = 0, |
| .attributeDefs[ FTDF_PIB_TSCH_ENABLED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TSCH_ENABLED ].setFunc = NULL, |
| #ifdef FTDF_NO_CSL |
| .attributeDefs[ FTDF_PIB_LE_ENABLED ].addr = &FTDF_pib.leEnabled, |
| .attributeDefs[ FTDF_PIB_LE_ENABLED ].size = 0, |
| .attributeDefs[ FTDF_PIB_LE_ENABLED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LE_ENABLED ].setFunc = NULL, |
| #else |
| .attributeDefs[ FTDF_PIB_LE_ENABLED ].addr = &FTDF_pib.leEnabled, |
| .attributeDefs[ FTDF_PIB_LE_ENABLED ].size = sizeof(FTDF_pib.leEnabled), |
| .attributeDefs[ FTDF_PIB_LE_ENABLED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LE_ENABLED ].setFunc = FTDF_setLeEnabled, |
| #endif /* FTDF_NO_CSL */ |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_CURRENT_CHANNEL ].addr = &FTDF_pib.currentChannel, |
| .attributeDefs[ FTDF_PIB_CURRENT_CHANNEL ].size = sizeof(FTDF_pib.currentChannel), |
| .attributeDefs[ FTDF_PIB_CURRENT_CHANNEL ].getFunc = FTDF_getCurrentChannel, |
| .attributeDefs[ FTDF_PIB_CURRENT_CHANNEL ].setFunc = FTDF_setCurrentChannel, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_CHANNELS_SUPPORTED ].addr = (void *) &channelsSupported, |
| .attributeDefs[ FTDF_PIB_CHANNELS_SUPPORTED ].size = 0, |
| .attributeDefs[ FTDF_PIB_CHANNELS_SUPPORTED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CHANNELS_SUPPORTED ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_TX_POWER_TOLERANCE ].addr = &FTDF_pib.TXPowerTolerance, |
| .attributeDefs[ FTDF_PIB_TX_POWER_TOLERANCE ].size = sizeof(FTDF_pib.TXPowerTolerance), |
| .attributeDefs[ FTDF_PIB_TX_POWER_TOLERANCE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TX_POWER_TOLERANCE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TX_POWER ].addr = &FTDF_pib.TXPower, |
| .attributeDefs[ FTDF_PIB_TX_POWER ].size = sizeof(FTDF_pib.TXPower), |
| .attributeDefs[ FTDF_PIB_TX_POWER ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TX_POWER ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CCA_MODE ].addr = &FTDF_pib.CCAMode, |
| .attributeDefs[ FTDF_PIB_CCA_MODE ].size = sizeof(FTDF_pib.CCAMode), |
| .attributeDefs[ FTDF_PIB_CCA_MODE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CCA_MODE ].setFunc = FTDF_setTXPower, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_CURRENT_PAGE ].addr = &FTDF_pib.currentPage, |
| .attributeDefs[ FTDF_PIB_CURRENT_PAGE ].size = 0, |
| .attributeDefs[ FTDF_PIB_CURRENT_PAGE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_CURRENT_PAGE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_DURATION ].addr = &FTDF_pib.maxFrameDuration, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_DURATION ].size = 0, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_DURATION ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_MAX_FRAME_DURATION ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SHR_DURATION ].addr = &FTDF_pib.SHRDuration, |
| .attributeDefs[ FTDF_PIB_SHR_DURATION ].size = 0, |
| .attributeDefs[ FTDF_PIB_SHR_DURATION ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_SHR_DURATION ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_TRAFFIC_COUNTERS ].addr = &FTDF_pib.trafficCounters, |
| .attributeDefs[ FTDF_PIB_TRAFFIC_COUNTERS ].size = 0, |
| .attributeDefs[ FTDF_PIB_TRAFFIC_COUNTERS ].getFunc = FTDF_getLmacTrafficCounters, |
| .attributeDefs[ FTDF_PIB_TRAFFIC_COUNTERS ].setFunc = NULL, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_LE_CAPABLE ].addr = &FTDF_pib.LECapable, |
| .attributeDefs[ FTDF_PIB_LE_CAPABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_LE_CAPABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LE_CAPABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LL_CAPABLE ].addr = &FTDF_pib.LLCapable, |
| .attributeDefs[ FTDF_PIB_LL_CAPABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_LL_CAPABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_LL_CAPABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DSME_CAPABLE ].addr = &FTDF_pib.DSMECapable, |
| .attributeDefs[ FTDF_PIB_DSME_CAPABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_DSME_CAPABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_DSME_CAPABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_RFID_CAPABLE ].addr = &FTDF_pib.RFIDCapable, |
| .attributeDefs[ FTDF_PIB_RFID_CAPABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_RFID_CAPABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_RFID_CAPABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_AMCA_CAPABLE ].addr = &FTDF_pib.AMCACapable, |
| .attributeDefs[ FTDF_PIB_AMCA_CAPABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_AMCA_CAPABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_AMCA_CAPABLE ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_METRICS_CAPABLE ].addr = &FTDF_pib.metricsCapable, |
| .attributeDefs[ FTDF_PIB_METRICS_CAPABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_METRICS_CAPABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_METRICS_CAPABLE ].setFunc = NULL, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_RANGING_SUPPORTED ].addr = &FTDF_pib.rangingSupported, |
| .attributeDefs[ FTDF_PIB_RANGING_SUPPORTED ].size = 0, |
| .attributeDefs[ FTDF_PIB_RANGING_SUPPORTED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_RANGING_SUPPORTED ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| .attributeDefs[ FTDF_PIB_KEEP_PHY_ENABLED ].addr = &FTDF_pib.keepPhyEnabled, |
| .attributeDefs[ FTDF_PIB_KEEP_PHY_ENABLED ].size = sizeof(FTDF_pib.keepPhyEnabled), |
| .attributeDefs[ FTDF_PIB_KEEP_PHY_ENABLED ].getFunc = FTDF_getKeepPhyEnabled, |
| .attributeDefs[ FTDF_PIB_KEEP_PHY_ENABLED ].setFunc = FTDF_setKeepPhyEnabled, |
| .attributeDefs[ FTDF_PIB_METRICS_ENABLED ].addr = &FTDF_pib.metricsEnabled, |
| .attributeDefs[ FTDF_PIB_METRICS_ENABLED ].size = sizeof(FTDF_pib.metricsEnabled), |
| .attributeDefs[ FTDF_PIB_METRICS_ENABLED ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_METRICS_ENABLED ].setFunc = NULL, |
| #ifndef FTDF_LITE |
| .attributeDefs[ FTDF_PIB_BEACON_AUTO_RESPOND ].addr = &FTDF_pib.beaconAutoRespond, |
| .attributeDefs[ FTDF_PIB_BEACON_AUTO_RESPOND ].size = sizeof(FTDF_pib.beaconAutoRespond), |
| .attributeDefs[ FTDF_PIB_BEACON_AUTO_RESPOND ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_BEACON_AUTO_RESPOND ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TSCH_CAPABLE ].addr = &FTDF_pib.tschCapable, |
| .attributeDefs[ FTDF_PIB_TSCH_CAPABLE ].size = 0, |
| .attributeDefs[ FTDF_PIB_TSCH_CAPABLE ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TSCH_CAPABLE ].setFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TS_SYNC_CORRECT_THRESHOLD ].addr = &FTDF_pib.tsSyncCorrectThreshold, |
| .attributeDefs[ FTDF_PIB_TS_SYNC_CORRECT_THRESHOLD ].size = sizeof(FTDF_pib.tsSyncCorrectThreshold), |
| .attributeDefs[ FTDF_PIB_TS_SYNC_CORRECT_THRESHOLD ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_TS_SYNC_CORRECT_THRESHOLD ].setFunc = NULL, |
| #endif /* !FTDF_LITE */ |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| .attributeDefs[ FTDF_PIB_BO_IRQ_THRESHOLD ].addr = &FTDF_pib.boIrqThreshold, |
| .attributeDefs[ FTDF_PIB_BO_IRQ_THRESHOLD ].size = sizeof(FTDF_pib.boIrqThreshold), |
| .attributeDefs[ FTDF_PIB_BO_IRQ_THRESHOLD ].getFunc = FTDF_getBoIrqThreshold, |
| .attributeDefs[ FTDF_PIB_BO_IRQ_THRESHOLD ].setFunc = FTDF_setBoIrqThreshold, |
| .attributeDefs[ FTDF_PIB_PTI_CONFIG ].addr = &FTDF_pib.ptiConfig, |
| .attributeDefs[ FTDF_PIB_PTI_CONFIG ].size = sizeof(FTDF_pib.ptiConfig), |
| .attributeDefs[ FTDF_PIB_PTI_CONFIG ].getFunc = NULL, |
| .attributeDefs[ FTDF_PIB_PTI_CONFIG ].setFunc = FTDF_setPtiConfig, |
| #endif /* dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */ |
| }; |
| |
| FTDF_Boolean FTDF_transparentMode __attribute__((section(".retention"))); |
| FTDF_Bitmap32 FTDF_transparentModeOptions __attribute__((section(".retention"))); |
| #if FTDF_DBG_BUS_ENABLE |
| FTDF_DbgMode FTDF_dbgMode __attribute__((section(".retention"))); |
| #endif |
| #if dg_configUSE_FTDF_DDPHY == 1 |
| uint16_t FTDF_ddphyCcaReg __attribute__((section(".retention"))); |
| #endif |
| #ifndef FTDF_LITE |
| FTDF_Buffer FTDF_reqBuffers[ FTDF_NR_OF_REQ_BUFFERS ] __attribute__((section(".retention"))); |
| FTDF_Queue FTDF_reqQueue __attribute__((section(".retention"))); |
| FTDF_Queue FTDF_freeQueue __attribute__((section(".retention"))); |
| FTDF_Pending FTDF_txPendingList[ FTDF_NR_OF_REQ_BUFFERS ] __attribute__((section(".retention"))); |
| FTDF_PendingTL FTDF_txPendingTimerList[ FTDF_NR_OF_REQ_BUFFERS ] __attribute__((section(".retention"))); |
| FTDF_PendingTL *FTDF_txPendingTimerHead __attribute__((section(".retention"))); |
| FTDF_Time FTDF_txPendingTimerLT __attribute__((section(".retention"))); |
| FTDF_Time FTDF_txPendingTimerTime __attribute__((section(".retention"))); |
| #endif /* !FTDF_LITE */ |
| #ifndef FTDF_PHY_API |
| FTDF_MsgBuffer *FTDF_reqCurrent __attribute__((section(".retention"))); |
| #endif |
| FTDF_Size FTDF_nrOfRetries __attribute__((section(".retention"))); |
| #if FTDF_USE_SLEEP_DURING_BACKOFF |
| static FTDF_Sdb FTDF_sdb __attribute__((section(".retention"))); |
| #endif /* FTDF_USE_SLEEP_DURING_BACKOFF */ |
| #ifndef FTDF_LITE |
| FTDF_Boolean FTDF_isPANCoordinator __attribute__((section(".retention"))); |
| FTDF_Time FTDF_startCslSampleTime __attribute__((section(".retention"))); |
| FTDF_RxAddressAdmin FTDF_rxa[ FTDF_NR_OF_RX_ADDRS ] __attribute__((section(".retention"))); |
| #endif /* !FTDF_LITE */ |
| FTDF_Boolean FTDF_txInProgress __attribute__((section(".retention"))); |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_CSL |
| FTDF_PeerCslTiming FTDF_peerCslTiming[ FTDF_NR_OF_CSL_PEERS ] __attribute__((section(".retention"))); |
| FTDF_Boolean FTDF_oldLeEnabled __attribute__((section(".retention"))); |
| FTDF_Time FTDF_rzTime __attribute__((section(".retention"))); |
| FTDF_ShortAddress FTDF_sendFramePending __attribute__((section(".retention"))); |
| #endif /* FTDF_NO_CSL */ |
| #endif /* !FTDF_LITE */ |
| uint32_t FTDF_curTime[ 2 ] __attribute__((section(".retention"))); |
| FTDF_LmacCounters FTDF_lmacCounters __attribute__((section(".retention"))); |
| FTDF_FrameHeader FTDF_fh; |
| #ifndef FTDF_LITE |
| FTDF_SecurityHeader FTDF_sh; |
| FTDF_AssocAdmin FTDF_aa; |
| #endif /* !FTDF_LITE */ |
| |
| #if FTDF_USE_PTI |
| /* Packet traffic information used when FTDF is in RX enable. */ |
| static FTDF_PTI FTDF_RxPti __attribute__((section(".retention"))); |
| #endif |
| static void sendConfirm(FTDF_Status status, |
| FTDF_MsgId msgId); |
| |
| void FTDF_reset(int setDefaultPIB) |
| { |
| if (setDefaultPIB) |
| { |
| // Reset PIB values to their default values |
| memset(&FTDF_pib, 0, sizeof(FTDF_pib)); |
| |
| FTDF_pib.extAddress = FTDF_GET_EXT_ADDRESS(); |
| FTDF_pib.ackWaitDuration = 0x36; |
| #ifndef FTDF_LITE |
| FTDF_pib.autoRequest = FTDF_TRUE; |
| FTDF_pib.beaconOrder = 15; |
| FTDF_pib.DSN = FTDF_pib.extAddress & 0xff; |
| FTDF_pib.BSN = FTDF_pib.extAddress & 0xff; |
| FTDF_pib.EBSN = FTDF_pib.extAddress & 0xff; |
| FTDF_pib.coordShortAddress = 0xffff; |
| #endif /* !FTDF_LITE */ |
| FTDF_pib.maxBE = 5; |
| FTDF_pib.maxCSMABackoffs = 4; |
| FTDF_pib.maxFrameTotalWaitTime = 1026; // see asic_vol v40.100.2.30 PR2540 |
| FTDF_pib.maxFrameRetries = 3; |
| FTDF_pib.minBE = 3; |
| #ifndef FTDF_LITE |
| FTDF_pib.LIFSPeriod = 40; |
| FTDF_pib.SIFSPeriod = 12; |
| #endif /* !FTDF_LITE */ |
| FTDF_pib.PANId = 0xffff; |
| #ifndef FTDF_LITE |
| FTDF_pib.responseWaitTime = 32; |
| #endif /* !FTDF_LITE */ |
| FTDF_pib.shortAddress = 0xffff; |
| #ifndef FTDF_LITE |
| FTDF_pib.superframeOrder = 15; |
| FTDF_pib.timestampSupported = FTDF_TRUE; |
| FTDF_pib.transactionPersistenceTime = 0x1f4; |
| FTDF_pib.enhAckWaitDuration = 0x360; |
| FTDF_pib.EBAutoSA = FTDF_AUTO_FULL; |
| #endif /* !FTDF_LITE */ |
| FTDF_pib.currentChannel = 11; |
| FTDF_pib.CCAMode = FTDF_CCA_MODE_1; |
| #ifndef FTDF_LITE |
| FTDF_pib.maxFrameDuration = FTDF_TBD; |
| FTDF_pib.SHRDuration = FTDF_TBD; |
| FTDF_pib.frameCounterMode = 4; |
| #endif /* !FTDF_LITE */ |
| FTDF_pib.metricsCapable = FTDF_TRUE; |
| #ifndef FTDF_LITE |
| FTDF_pib.beaconAutoRespond = FTDF_TRUE; |
| #endif /* !FTDF_LITE */ |
| FTDF_pib.performanceMetrics.counterOctets = 4; // 32 bit counters |
| #ifndef FTDF_LITE |
| FTDF_pib.joinPriority = 1; |
| FTDF_pib.slotframeTable.slotframeEntries = FTDF_slotframeTable; |
| FTDF_pib.linkTable.linkEntries = FTDF_linkTable; |
| FTDF_pib.timeslotTemplate.tsCCAOffset = 1800; |
| FTDF_pib.timeslotTemplate.tsCCA = 128; |
| FTDF_pib.timeslotTemplate.tsTxOffset = 2120; |
| FTDF_pib.timeslotTemplate.tsRxOffset = 1020; |
| FTDF_pib.timeslotTemplate.tsRxAckDelay = 800; |
| FTDF_pib.timeslotTemplate.tsTxAckDelay = 1000; |
| FTDF_pib.timeslotTemplate.tsRxWait = 2200; |
| FTDF_pib.timeslotTemplate.tsAckWait = 400; |
| FTDF_pib.timeslotTemplate.tsRxTx = 192; |
| FTDF_pib.timeslotTemplate.tsMaxAck = 2400; |
| FTDF_pib.timeslotTemplate.tsMaxTs = 4256; |
| FTDF_pib.timeslotTemplate.tsTimeslotLength = 10000; |
| FTDF_pib.tsSyncCorrectThreshold = 220; |
| FTDF_pib.hoppingSequenceLength = 16; |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| int i; |
| |
| for (i = 0; i < FTDF_PTIS; i++) |
| { |
| FTDF_pib.ptiConfig.ptis[i] = 0; |
| } |
| |
| #endif |
| #ifdef FTDF_NO_CSL |
| FTDF_pib.LECapable = FTDF_FALSE; |
| #else |
| FTDF_pib.LECapable = FTDF_TRUE; |
| #endif /* FTDF_NO_CSL */ |
| #ifdef FTDF_NO_TSCH |
| FTDF_pib.tschCapable = FTDF_FALSE; |
| #else |
| FTDF_pib.tschCapable = FTDF_TRUE; |
| #endif /* FTDF_NO_TSCH */ |
| |
| int n; |
| |
| for (n = 0; n < FTDF_MAX_HOPPING_SEQUENCE_LENGTH; n++) |
| { |
| FTDF_pib.hoppingSequenceList[ n ] = n + 11; |
| } |
| |
| #endif /* !FTDF_LITE */ |
| |
| FTDF_transparentMode = FTDF_FALSE; |
| #ifndef FTDF_LITE |
| FTDF_isPANCoordinator = FTDF_FALSE; |
| #endif /* !FTDF_LITE */ |
| FTDF_lmacCounters.fcsErrorCnt = 0; |
| FTDF_lmacCounters.txStdAckCnt = 0; |
| FTDF_lmacCounters.rxStdAckCnt = 0; |
| |
| #ifndef FTDF_LITE |
| memset(FTDF_pib.defaultKeySource, 0xff, 8); |
| #endif /* !FTDF_LITE */ |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| FTDF_pib.boIrqThreshold = FTDF_BO_IRQ_THRESHOLD; |
| #endif /* #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */ |
| } |
| |
| FTDF_initQueues(); |
| |
| volatile uint32_t *lmacReset = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMACRESET); |
| *lmacReset = MSK_R_FTDF_ON_OFF_REGMAP_LMACRESET; |
| |
| volatile uint32_t *controlStatus = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_CONTROL_STATUS); |
| uint32_t wait = 0; |
| |
| while ((*controlStatus & MSK_F_FTDF_ON_OFF_REGMAP_LMACREADY4SLEEP) == 0) |
| { |
| wait++; |
| } |
| |
| volatile uint32_t *wakeupTimerEnableStatus = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS); |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPTIMERENABLE, 0); |
| |
| #else |
| FTDF_SET_FIELD(ON_OFF_REGMAP_WAKEUPTIMERENABLE_CLEAR, 1); |
| #endif |
| |
| while (*wakeupTimerEnableStatus & MSK_F_FTDF_ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS) |
| { } |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| FTDF_SET_FIELD(ALWAYS_ON_REGMAP_WAKEUPTIMERENABLE, 1); |
| |
| #else |
| FTDF_SET_FIELD(ON_OFF_REGMAP_WAKEUPTIMERENABLE_SET, 1); |
| #endif |
| |
| while ((*wakeupTimerEnableStatus & MSK_F_FTDF_ON_OFF_REGMAP_WAKEUPTIMERENABLESTATUS) == 0) |
| { } |
| |
| #ifndef FTDF_LITE |
| int n; |
| |
| #ifndef FTDF_NO_CSL |
| |
| for (n = 0; n < FTDF_NR_OF_CSL_PEERS; n++) |
| { |
| FTDF_peerCslTiming[ n ].addr = 0xffff; |
| } |
| |
| FTDF_oldLeEnabled = FTDF_FALSE; |
| FTDF_wakeUpEnableLe = FTDF_FALSE; |
| FTDF_sendFramePending = 0xfffe; |
| #endif /* FTDF_NO_CSL */ |
| #endif /* !FTDF_LITE */ |
| FTDF_txInProgress = FTDF_FALSE; |
| |
| FTDF_initCurTime64(); |
| #ifndef FTDF_NO_TSCH |
| FTDF_initTschRetries(); |
| FTDF_initBackoff(); |
| #endif /* FTDF_NO_TSCH */ |
| |
| #ifndef FTDF_LITE |
| |
| for (n = 0; n < FTDF_NR_OF_RX_ADDRS; n++) |
| { |
| FTDF_rxa[ n ].addrMode = FTDF_NO_ADDRESS; |
| FTDF_rxa[ n ].dsnValid = FTDF_FALSE; |
| FTDF_rxa[ n ].bsnValid = FTDF_FALSE; |
| FTDF_rxa[ n ].ebsnValid = FTDF_FALSE; |
| } |
| |
| #ifndef FTDF_NO_TSCH |
| |
| for (n = 0; n < FTDF_NR_OF_NEIGHBORS; n++) |
| { |
| FTDF_neighborTable[ n ].dstAddr = 0xffff; |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| #if FTDF_USE_SLEEP_DURING_BACKOFF |
| FTDF_sdbFsmReset(); |
| #endif /* FTDF_USE_SLEEP_DURING_BACKOFF */ |
| FTDF_initLmac(); |
| |
| #ifndef FTDF_NO_CSL |
| FTDF_rzTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| #endif /* FTDF_NO_CSL */ |
| |
| #if dg_configUSE_FTDF_DDPHY == 1 |
| FTDF_ddphySet(0); |
| #endif |
| } |
| |
| #ifndef FTDF_PHY_API |
| void FTDF_processResetRequest(FTDF_ResetRequest *resetRequest) |
| { |
| |
| FTDF_reset(resetRequest->setDefaultPIB); |
| FTDF_ResetConfirm *resetConfirm = (FTDF_ResetConfirm *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_ResetConfirm)); |
| |
| resetConfirm->msgId = FTDF_RESET_CONFIRM; |
| resetConfirm->status = FTDF_SUCCESS; |
| |
| FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) resetRequest); |
| |
| FTDF_RCV_MSG((FTDF_MsgBuffer *) resetConfirm); |
| } |
| #endif /* FTDF_PHY_API */ |
| |
| void FTDF_initLmac(void) |
| { |
| FTDF_PIBAttribute PIBAttribute; |
| |
| for (PIBAttribute = 1; PIBAttribute <= FTDF_NR_OF_PIB_ATTRIBUTES; PIBAttribute++) |
| { |
| if (pibAttributeTable.attributeDefs[ PIBAttribute ].setFunc != NULL) |
| { |
| pibAttributeTable.attributeDefs[ PIBAttribute ].setFunc(); |
| } |
| } |
| |
| if (FTDF_transparentMode == FTDF_TRUE) |
| { |
| FTDF_enableTransparentMode(FTDF_TRUE, FTDF_transparentModeOptions); |
| } |
| |
| #ifndef FTDF_LITE |
| |
| if (FTDF_isPANCoordinator) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_ISPANCOORDINATOR, 1); |
| } |
| |
| #endif /* !FTDF_LITE */ |
| FTDF_SET_FIELD(ON_OFF_REGMAP_CCAIDLEWAIT, 192); |
| |
| volatile uint32_t *txFlagClear = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_CLEAR); |
| *txFlagClear = MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR; |
| |
| volatile uint32_t *phyParams = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_PHY_PARAMETERS_2); |
| *phyParams = (FTDF_PHYTXSTARTUP << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXSTARTUP) | |
| (FTDF_PHYTXLATENCY << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXLATENCY) | |
| (FTDF_PHYTXFINISH << OFF_F_FTDF_ON_OFF_REGMAP_PHYTXFINISH) | |
| (FTDF_PHYTRXWAIT << OFF_F_FTDF_ON_OFF_REGMAP_PHYTRXWAIT); |
| |
| phyParams = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_PHY_PARAMETERS_3); |
| *phyParams = (FTDF_PHYRXSTARTUP << OFF_F_FTDF_ON_OFF_REGMAP_PHYRXSTARTUP) | |
| (FTDF_PHYRXLATENCY << OFF_F_FTDF_ON_OFF_REGMAP_PHYRXLATENCY) | |
| (FTDF_PHYENABLE << OFF_F_FTDF_ON_OFF_REGMAP_PHYENABLE); |
| |
| volatile uint32_t *ftdfCm = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_FTDF_CM); |
| *ftdfCm = FTDF_MSK_TX_CE | FTDF_MSK_RX_CE | FTDF_MSK_SYMBOL_TMR_CE; |
| |
| volatile uint32_t *rxMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_RX_MASK); |
| *rxMask = MSK_R_FTDF_ON_OFF_REGMAP_RX_MASK; |
| |
| volatile uint32_t *lmacMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_MASK); |
| *lmacMask = MSK_F_FTDF_ON_OFF_REGMAP_RXTIMEREXPIRED_M; |
| |
| volatile uint32_t *lmacCtrlMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_CONTROL_MASK); |
| *lmacCtrlMask = MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIMETHR_M | |
| MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIME2THR_M | |
| MSK_F_FTDF_ON_OFF_REGMAP_SYNCTIMESTAMP_M; |
| |
| volatile uint32_t *txFlagClearM; |
| txFlagClearM = FTDF_GET_FIELD_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_CLEAR_M, FTDF_TX_DATA_BUFFER); |
| *txFlagClearM |= MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_M; |
| txFlagClearM = FTDF_GET_FIELD_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_CLEAR_M, FTDF_TX_WAKEUP_BUFFER); |
| *txFlagClearM |= MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_M; |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| #if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO |
| FTDF_fpprReset(); |
| FTDF_fpprSetMode(FTDF_TRUE, FTDF_FALSE, FTDF_FALSE); |
| #else |
| FTDF_fpprSetMode(FTDF_FALSE, FTDF_TRUE, FTDF_TRUE); |
| #endif /* #if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */ |
| #if FTDF_USE_SLEEP_DURING_BACKOFF |
| /* Unmask long BO interrupt. */ |
| FTDF_SET_FIELD(ON_OFF_REGMAP_CSMA_CA_BO_THR_M, 1); |
| #else /* FTDF_USE_SLEEP_DURING_BACKOFF */ |
| /* Set BO threshold. */ |
| FTDF_SET_FIELD(ON_OFF_REGMAP_CSMA_CA_BO_THRESHOLD, FTDF_BO_IRQ_THRESHOLD); |
| |
| /* Mask long BO interrupt. */ |
| FTDF_SET_FIELD(ON_OFF_REGMAP_CSMA_CA_BO_THR_M, 0); |
| #endif /* FTDF_USE_SLEEP_DURING_BACKOFF */ |
| #if FTDF_USE_LPDP == 1 |
| FTDF_lpdpEnable(FTDF_TRUE); |
| #endif /* #if FTDF_USE_LPDP == 1 */ |
| #endif /* #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */ |
| } |
| |
| #ifdef FTDF_PHY_API |
| FTDF_PIBAttributeValue *FTDF_getValue(FTDF_PIBAttribute PIBAttribute) |
| { |
| |
| if (PIBAttribute <= FTDF_NR_OF_PIB_ATTRIBUTES && |
| pibAttributeTable.attributeDefs[ PIBAttribute ].addr != NULL) |
| { |
| // Update PIB attribute with current LMAC status if a getFunc is defined |
| if (pibAttributeTable.attributeDefs[ PIBAttribute ].getFunc != NULL) |
| { |
| pibAttributeTable.attributeDefs[ PIBAttribute ].getFunc(); |
| } |
| |
| return pibAttributeTable.attributeDefs[ PIBAttribute ].addr; |
| } |
| |
| return NULL; |
| } |
| |
| FTDF_Status FTDF_setValue(FTDF_PIBAttribute PIBAttribute, const FTDF_PIBAttributeValue *PIBAttributeValue) |
| { |
| if (PIBAttribute <= FTDF_NR_OF_PIB_ATTRIBUTES && |
| pibAttributeTable.attributeDefs[ PIBAttribute ].addr != NULL) |
| { |
| if (pibAttributeTable.attributeDefs[ PIBAttribute ].size != 0) |
| { |
| memcpy(pibAttributeTable.attributeDefs[ PIBAttribute ].addr, |
| PIBAttributeValue, |
| pibAttributeTable.attributeDefs[ PIBAttribute ].size); |
| |
| // Update LMAC with new PIB attribute value if a setFunc is defined |
| if (pibAttributeTable.attributeDefs[ PIBAttribute ].setFunc != NULL) |
| { |
| pibAttributeTable.attributeDefs[ PIBAttribute ].setFunc(); |
| } |
| |
| return FTDF_SUCCESS; |
| |
| } |
| else |
| { |
| return FTDF_READ_ONLY; |
| } |
| } |
| |
| return FTDF_UNSUPPORTED_ATTRIBUTE; |
| } |
| |
| #else /* FTDF_PHY_API */ |
| void FTDF_processGetRequest(FTDF_GetRequest *getRequest) |
| { |
| FTDF_GetConfirm *getConfirm = (FTDF_GetConfirm *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_GetConfirm)); |
| FTDF_PIBAttribute PIBAttribute = getRequest->PIBAttribute; |
| |
| getConfirm->msgId = FTDF_GET_CONFIRM; |
| getConfirm->PIBAttribute = PIBAttribute; |
| |
| if (PIBAttribute <= FTDF_NR_OF_PIB_ATTRIBUTES && |
| pibAttributeTable.attributeDefs[ PIBAttribute ].addr != NULL) |
| { |
| // Update PIB attribute with current LMAC status if a getFunc is defined |
| if (pibAttributeTable.attributeDefs[ PIBAttribute ].getFunc != NULL) |
| { |
| pibAttributeTable.attributeDefs[ PIBAttribute ].getFunc(); |
| } |
| |
| getConfirm->status = FTDF_SUCCESS; |
| getConfirm->PIBAttributeValue = pibAttributeTable.attributeDefs[ PIBAttribute ].addr; |
| } |
| else |
| { |
| getConfirm->status = FTDF_UNSUPPORTED_ATTRIBUTE; |
| } |
| |
| FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) getRequest); |
| |
| FTDF_RCV_MSG((FTDF_MsgBuffer *) getConfirm); |
| } |
| |
| void FTDF_processSetRequest(FTDF_SetRequest *setRequest) |
| { |
| FTDF_SetConfirm *setConfirm = (FTDF_SetConfirm *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_SetConfirm)); |
| FTDF_PIBAttribute PIBAttribute = setRequest->PIBAttribute; |
| |
| setConfirm->msgId = FTDF_SET_CONFIRM; |
| setConfirm->PIBAttribute = PIBAttribute; |
| |
| if (PIBAttribute <= FTDF_NR_OF_PIB_ATTRIBUTES && |
| pibAttributeTable.attributeDefs[ PIBAttribute ].addr != NULL) |
| { |
| if (pibAttributeTable.attributeDefs[ PIBAttribute ].size != 0) |
| { |
| setConfirm->status = FTDF_SUCCESS; |
| memcpy(pibAttributeTable.attributeDefs[ PIBAttribute ].addr, |
| setRequest->PIBAttributeValue, |
| pibAttributeTable.attributeDefs[ PIBAttribute ].size); |
| |
| // Update LMAC with new PIB attribute value if a setFunc is defined |
| if (pibAttributeTable.attributeDefs[ PIBAttribute ].setFunc != NULL) |
| { |
| pibAttributeTable.attributeDefs[ PIBAttribute ].setFunc(); |
| } |
| } |
| else |
| { |
| setConfirm->status = FTDF_READ_ONLY; |
| } |
| } |
| else |
| { |
| setConfirm->status = FTDF_UNSUPPORTED_ATTRIBUTE; |
| } |
| |
| FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) setRequest); |
| |
| FTDF_RCV_MSG((FTDF_MsgBuffer *) setConfirm); |
| } |
| |
| |
| void FTDF_sendCommStatusIndication(FTDF_MsgBuffer *request, |
| FTDF_Status status, |
| FTDF_PANId PANId, |
| FTDF_AddressMode srcAddrMode, |
| FTDF_Address srcAddr, |
| FTDF_AddressMode dstAddrMode, |
| FTDF_Address dstAddr, |
| FTDF_SecurityLevel securityLevel, |
| FTDF_KeyIdMode keyIdMode, |
| FTDF_Octet *keySource, |
| FTDF_KeyIndex keyIndex) |
| { |
| FTDF_CommStatusIndication *commStatus = |
| (FTDF_CommStatusIndication *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_CommStatusIndication)); |
| |
| commStatus->msgId = FTDF_COMM_STATUS_INDICATION; |
| commStatus->PANId = PANId; |
| commStatus->srcAddrMode = srcAddrMode; |
| commStatus->srcAddr = srcAddr; |
| commStatus->dstAddrMode = dstAddrMode; |
| commStatus->dstAddr = dstAddr; |
| commStatus->status = status; |
| commStatus->securityLevel = securityLevel; |
| commStatus->keyIdMode = keyIdMode; |
| commStatus->keyIndex = keyIndex; |
| |
| uint8_t n; |
| |
| if (securityLevel != 0) |
| { |
| if (keyIdMode == 0x2) |
| { |
| for (n = 0; n < 4; n++) |
| { |
| commStatus->keySource[ n ] = keySource[ n ]; |
| } |
| } |
| else if (keyIdMode == 0x3) |
| { |
| for (n = 0; n < 8; n++) |
| { |
| commStatus->keySource[ n ] = keySource[ n ]; |
| } |
| } |
| } |
| |
| #ifndef FTDF_LITE |
| |
| if (request && |
| (request->msgId == FTDF_ORPHAN_RESPONSE || |
| request->msgId == FTDF_ASSOCIATE_RESPONSE)) |
| { |
| if (FTDF_reqCurrent == request) |
| { |
| FTDF_reqCurrent = NULL; |
| } |
| |
| FTDF_REL_MSG_BUFFER(request); |
| FTDF_RCV_MSG((FTDF_MsgBuffer *) commStatus); |
| /* Check for orphan response. */ |
| #if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO |
| FTDF_fpFsmClearPending(); |
| #endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */ |
| FTDF_processNextRequest(); |
| return; |
| } |
| |
| #endif /* !FTDF_LITE */ |
| FTDF_RCV_MSG((FTDF_MsgBuffer *) commStatus); |
| } |
| #endif /* FTDF_PHY_API */ |
| |
| #ifndef FTDF_LITE |
| FTDF_Octet *FTDF_addFrameHeader(FTDF_Octet *txPtr, |
| FTDF_FrameHeader *frameHeader, |
| FTDF_DataLength msduLength) |
| { |
| uint8_t frameVersion; |
| uint8_t longFrameControl = 0x00; |
| FTDF_Boolean panIdCompression = FTDF_FALSE; |
| FTDF_Bitmap8 options = frameHeader->options; |
| FTDF_Boolean secure = options & FTDF_OPT_SECURITY_ENABLED; |
| FTDF_Boolean framePending = options & FTDF_OPT_FRAME_PENDING; |
| FTDF_Boolean ackTX = options & FTDF_OPT_ACK_REQUESTED; |
| FTDF_Boolean panIdPresent = options & FTDF_OPT_PAN_ID_PRESENT; |
| FTDF_Boolean seqNrSuppressed = options & FTDF_OPT_SEQ_NR_SUPPRESSED; |
| FTDF_Boolean iesIncluded = options & FTDF_OPT_IES_PRESENT; |
| FTDF_FrameType frameType = frameHeader->frameType; |
| FTDF_AddressMode dstAddrMode = frameHeader->dstAddrMode; |
| FTDF_AddressMode srcAddrMode = frameHeader->srcAddrMode; |
| FTDF_PANId dstPANId = frameHeader->dstPANId; |
| |
| if (frameType == FTDF_MULTIPURPOSE_FRAME) |
| { |
| if (options & (FTDF_OPT_SECURITY_ENABLED | FTDF_OPT_ACK_REQUESTED | FTDF_OPT_PAN_ID_PRESENT | |
| FTDF_OPT_IES_PRESENT | FTDF_OPT_SEQ_NR_SUPPRESSED | FTDF_OPT_FRAME_PENDING)) |
| { |
| longFrameControl = 0x08; |
| } |
| |
| // Frame control field byte 1 |
| *txPtr++ = 0x05 | longFrameControl | dstAddrMode << 4 | srcAddrMode << 6; |
| |
| if (longFrameControl) |
| { |
| // Frame control field byte 2 |
| *txPtr++ = |
| (panIdPresent ? 0x01 : 0x00) | |
| (secure ? 0x02 : 0x00) | |
| (seqNrSuppressed ? 0x04 : 0x00) | |
| (framePending ? 0x08 : 0x00) | |
| (ackTX ? 0x40 : 0x00) | |
| (iesIncluded ? 0x80 : 0x00); |
| } |
| } |
| else |
| { |
| // if ( panIdPresent || iesIncluded || seqNrSuppressed || ( options & FTDF_OPT_ENHANCED ) || FTDF_pib.tschEnabled ) |
| if (panIdPresent || iesIncluded || seqNrSuppressed || (options & FTDF_OPT_ENHANCED)) |
| { |
| frameVersion = 0b10; |
| } |
| else |
| { |
| if (secure || |
| msduLength > FTDF_MAX_MAC_SAFE_PAYLOAD_SIZE) |
| { |
| frameVersion = 0b01; |
| } |
| else |
| { |
| frameVersion = 0b00; |
| } |
| } |
| |
| if (frameVersion < 0b10) |
| { |
| if (dstAddrMode != FTDF_NO_ADDRESS && |
| srcAddrMode != FTDF_NO_ADDRESS && |
| dstPANId == frameHeader->srcPANId) |
| { |
| panIdCompression = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| panIdCompression = panIdPresent; |
| } |
| |
| // Frame control field byte 1 |
| *txPtr++ = |
| (frameType & 0x7) | |
| (secure ? 0x08 : 0x00) | |
| (framePending ? 0x10 : 0x00) | |
| (ackTX ? 0x20 : 0x00) | |
| (panIdCompression ? 0x40 : 0x00); |
| |
| // Frame control field byte 2 |
| *txPtr++ = |
| (seqNrSuppressed ? 0x01 : 0x00) | |
| (iesIncluded ? 0x02 : 0x00) | |
| dstAddrMode << 2 | |
| frameVersion << 4 | |
| srcAddrMode << 6; |
| } |
| |
| if (!seqNrSuppressed) |
| { |
| *txPtr++ = frameHeader->SN; |
| } |
| |
| FTDF_Boolean addDstPANId = FTDF_FALSE; |
| |
| if (frameType == FTDF_MULTIPURPOSE_FRAME) |
| { |
| if (panIdPresent) |
| { |
| addDstPANId = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| if (frameVersion < 0b10) |
| { |
| if (dstAddrMode != FTDF_NO_ADDRESS) |
| { |
| addDstPANId = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| // See Table 2a "PAN ID Compression" of IEEE 802.15.4-2011 for more details |
| if ((srcAddrMode == FTDF_NO_ADDRESS && dstAddrMode == FTDF_NO_ADDRESS && panIdCompression) || |
| (srcAddrMode == FTDF_NO_ADDRESS && dstAddrMode != FTDF_NO_ADDRESS && !panIdCompression) || |
| (srcAddrMode != FTDF_NO_ADDRESS && dstAddrMode != FTDF_NO_ADDRESS && !panIdCompression)) |
| { |
| addDstPANId = FTDF_TRUE; |
| } |
| } |
| } |
| |
| if (addDstPANId) |
| { |
| FTDF_Octet *PANIdPtr = (FTDF_Octet *)&dstPANId; |
| |
| *txPtr++ = *PANIdPtr++; |
| *txPtr++ = *PANIdPtr; |
| } |
| |
| FTDF_Address dstAddr = frameHeader->dstAddr; |
| |
| if (dstAddrMode == FTDF_SIMPLE_ADDRESS) |
| { |
| *txPtr++ = dstAddr.simpleAddress; |
| } |
| else if (dstAddrMode == FTDF_SHORT_ADDRESS) |
| { |
| FTDF_Octet *shortAddressPtr = (FTDF_Octet *)&dstAddr.shortAddress; |
| |
| *txPtr++ = *shortAddressPtr++; |
| *txPtr++ = *shortAddressPtr; |
| } |
| else if (dstAddrMode == FTDF_EXTENDED_ADDRESS) |
| { |
| FTDF_Octet *extAddressPtr = (FTDF_Octet *)&dstAddr.extAddress; |
| int n; |
| |
| for (n = 0; n < 8; n++) |
| { |
| *txPtr++ = *extAddressPtr++; |
| } |
| } |
| |
| FTDF_Boolean addSrcPANId = FTDF_FALSE; |
| |
| if (frameType != FTDF_MULTIPURPOSE_FRAME) |
| { |
| if (frameVersion < 0b10) |
| { |
| if (srcAddrMode != FTDF_NO_ADDRESS && !panIdCompression) |
| { |
| addSrcPANId = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| // See Table 2a "PAN ID Compression" of IEEE 802.15.4-2011 for more details |
| if (srcAddrMode != FTDF_NO_ADDRESS && dstAddrMode == FTDF_NO_ADDRESS && !panIdCompression) |
| { |
| addSrcPANId = FTDF_TRUE; |
| } |
| } |
| } |
| |
| if (addSrcPANId) |
| { |
| FTDF_Octet *PANIdPtr = (FTDF_Octet *)&frameHeader->srcPANId; |
| |
| *txPtr++ = *PANIdPtr++; |
| *txPtr++ = *PANIdPtr; |
| } |
| |
| if (srcAddrMode == FTDF_SIMPLE_ADDRESS) |
| { |
| *txPtr++ = FTDF_pib.simpleAddress; |
| } |
| else if (srcAddrMode == FTDF_SHORT_ADDRESS) |
| { |
| FTDF_Octet *shortAddressPtr = (FTDF_Octet *)&FTDF_pib.shortAddress; |
| |
| *txPtr++ = *shortAddressPtr++; |
| *txPtr++ = *shortAddressPtr; |
| } |
| else if (srcAddrMode == FTDF_EXTENDED_ADDRESS) |
| { |
| FTDF_Octet *extAddressPtr = (FTDF_Octet *)&FTDF_pib.extAddress; |
| int n; |
| |
| for (n = 0; n < 8; n++) |
| { |
| *txPtr++ = *extAddressPtr++; |
| } |
| } |
| |
| return txPtr; |
| } |
| #endif /* !FTDF_LITE */ |
| |
| FTDF_PTI FTDF_getRxPti(void) |
| { |
| #if FTDF_USE_PTI |
| FTDF_PTI rx_pti; |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| rx_pti = FTDF_RxPti; |
| FTDF_exitCritical(); |
| return rx_pti; |
| #else |
| return 0; |
| #endif |
| } |
| |
| #ifdef FTDF_PHY_API |
| void FTDF_rxEnable(FTDF_Time rxOnDuration) |
| { |
| #if dg_configCOEX_ENABLE_CONFIG |
| /* We do not force decision here. It will be automatically made when FTDF begins |
| * transaction. |
| */ |
| hw_coex_update_ftdf_pti((hw_coex_pti_t) FTDF_getRxPti(), NULL, false); |
| #endif |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXONDURATION, rxOnDuration); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 1); |
| } |
| #else |
| void FTDF_processRxEnableRequest(FTDF_RxEnableRequest *rxEnableRequest) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXONDURATION, rxEnableRequest->rxOnDuration); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 1); |
| |
| FTDF_RxEnableConfirm *rxEnableConfirm = |
| (FTDF_RxEnableConfirm *) FTDF_GET_MSG_BUFFER(sizeof(FTDF_RxEnableConfirm)); |
| |
| rxEnableConfirm->msgId = FTDF_RX_ENABLE_CONFIRM; |
| rxEnableConfirm->status = FTDF_SUCCESS; |
| |
| FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) rxEnableRequest); |
| FTDF_RCV_MSG((FTDF_MsgBuffer *) rxEnableConfirm); |
| } |
| #endif /* FTDF_PHY_API */ |
| |
| FTDF_Octet *FTDF_getFrameHeader(FTDF_Octet *rxBuffer, |
| FTDF_FrameHeader *frameHeader) |
| { |
| FTDF_FrameType frameType = *rxBuffer & 0x07; |
| uint8_t frameVersion = 0; |
| FTDF_Bitmap8 options = 0; |
| FTDF_AddressMode dstAddrMode; |
| FTDF_AddressMode srcAddrMode; |
| FTDF_Boolean panIdCompression = FTDF_FALSE; |
| FTDF_Boolean panIdPresent = FTDF_FALSE; |
| |
| if (frameType == FTDF_MULTIPURPOSE_FRAME) |
| { |
| dstAddrMode = (*rxBuffer & 0x30) >> 4; |
| srcAddrMode = (*rxBuffer & 0xc0) >> 6; |
| |
| // Check Long Frame Control |
| if (*rxBuffer & 0x08) |
| { |
| rxBuffer++; |
| |
| panIdPresent = *rxBuffer & 0x01; |
| |
| if (*rxBuffer & 0x02) |
| { |
| options |= FTDF_OPT_SECURITY_ENABLED; |
| } |
| |
| if (*rxBuffer & 0x04) |
| { |
| options |= FTDF_OPT_SEQ_NR_SUPPRESSED; |
| } |
| |
| if (*rxBuffer & 0x08) |
| { |
| options |= FTDF_OPT_FRAME_PENDING; |
| } |
| |
| if (*rxBuffer & 0x40) |
| { |
| options |= FTDF_OPT_ACK_REQUESTED; |
| } |
| |
| if (*rxBuffer & 0x80) |
| { |
| options |= FTDF_OPT_IES_PRESENT; |
| } |
| |
| frameVersion = 0; |
| |
| frameHeader->frameVersion = FTDF_FRAME_VERSION_E; |
| |
| rxBuffer++; |
| } |
| else |
| { |
| rxBuffer++; |
| } |
| } |
| else |
| { |
| if (*rxBuffer & 0x08) |
| { |
| options |= FTDF_OPT_SECURITY_ENABLED; |
| } |
| |
| if (*rxBuffer & 0x10) |
| { |
| options |= FTDF_OPT_FRAME_PENDING; |
| } |
| |
| if (*rxBuffer & 0x20) |
| { |
| options |= FTDF_OPT_ACK_REQUESTED; |
| } |
| |
| panIdCompression = *rxBuffer & 0x40; |
| |
| rxBuffer++; |
| |
| frameVersion = (*rxBuffer & 0x30) >> 4; |
| |
| if (frameVersion == 0x02) |
| { |
| if (*rxBuffer & 0x01) |
| { |
| options |= FTDF_OPT_SEQ_NR_SUPPRESSED; |
| } |
| |
| if (*rxBuffer & 0x02) |
| { |
| options |= FTDF_OPT_IES_PRESENT; |
| } |
| |
| frameHeader->frameVersion = FTDF_FRAME_VERSION_E; |
| } |
| else if (frameVersion == 0x01) |
| { |
| frameHeader->frameVersion = FTDF_FRAME_VERSION_2011; |
| } |
| else if (frameVersion == 0x00) |
| { |
| frameHeader->frameVersion = FTDF_FRAME_VERSION_2003; |
| } |
| else |
| { |
| frameHeader->frameVersion = FTDF_FRAME_VERSION_NOT_SUPPORTED; |
| return rxBuffer; |
| } |
| |
| dstAddrMode = (*rxBuffer & 0x0c) >> 2; |
| srcAddrMode = (*rxBuffer & 0xc0) >> 6; |
| |
| rxBuffer++; |
| } |
| |
| if ((options & FTDF_OPT_SEQ_NR_SUPPRESSED) == 0) |
| { |
| frameHeader->SN = *rxBuffer++; |
| } |
| |
| FTDF_Boolean hasDstPANId = FTDF_FALSE; |
| |
| if (frameType == FTDF_MULTIPURPOSE_FRAME) |
| { |
| hasDstPANId = panIdPresent; |
| } |
| else |
| { |
| if (frameVersion < 0x02) |
| { |
| if (dstAddrMode != FTDF_NO_ADDRESS) |
| { |
| hasDstPANId = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| if ((srcAddrMode == FTDF_NO_ADDRESS && dstAddrMode == FTDF_NO_ADDRESS && panIdCompression) || |
| (srcAddrMode == FTDF_NO_ADDRESS && dstAddrMode != FTDF_NO_ADDRESS && !panIdCompression) || |
| (srcAddrMode != FTDF_NO_ADDRESS && dstAddrMode != FTDF_NO_ADDRESS && !panIdCompression)) |
| { |
| hasDstPANId = FTDF_TRUE; |
| } |
| } |
| } |
| |
| if (hasDstPANId) |
| { |
| FTDF_Octet *PANIdPtr = (FTDF_Octet *) &frameHeader->dstPANId; |
| |
| *PANIdPtr++ = *rxBuffer++; |
| *PANIdPtr = *rxBuffer++; |
| } |
| |
| if (dstAddrMode == FTDF_SIMPLE_ADDRESS) |
| { |
| frameHeader->dstAddr.simpleAddress = *rxBuffer++; |
| } |
| else if (dstAddrMode == FTDF_SHORT_ADDRESS) |
| { |
| FTDF_Octet *shortAddressPtr = (FTDF_Octet *)&frameHeader->dstAddr.shortAddress; |
| |
| *shortAddressPtr++ = *rxBuffer++; |
| *shortAddressPtr = *rxBuffer++; |
| } |
| else if (dstAddrMode == FTDF_EXTENDED_ADDRESS) |
| { |
| FTDF_Octet *extAddressPtr = (FTDF_Octet *)&frameHeader->dstAddr.extAddress; |
| int n; |
| |
| for (n = 0; n < 8; n++) |
| { |
| *extAddressPtr++ = *rxBuffer++; |
| } |
| } |
| |
| FTDF_Boolean hasSrcPANId = FTDF_FALSE; |
| |
| if (frameVersion < 0x02 && frameType != FTDF_MULTIPURPOSE_FRAME) |
| { |
| if (srcAddrMode != FTDF_NO_ADDRESS && !panIdCompression) |
| { |
| hasSrcPANId = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| if (srcAddrMode != FTDF_NO_ADDRESS && dstAddrMode == FTDF_NO_ADDRESS && !panIdCompression) |
| { |
| hasSrcPANId = FTDF_TRUE; |
| } |
| } |
| |
| if (hasSrcPANId) |
| { |
| FTDF_Octet *PANIdPtr = (FTDF_Octet *) &frameHeader->srcPANId; |
| |
| *PANIdPtr++ = *rxBuffer++; |
| *PANIdPtr = *rxBuffer++; |
| } |
| else |
| { |
| frameHeader->srcPANId = frameHeader->dstPANId; |
| } |
| |
| if (srcAddrMode == FTDF_SIMPLE_ADDRESS) |
| { |
| frameHeader->srcAddr.simpleAddress = *rxBuffer++; |
| } |
| else if (srcAddrMode == FTDF_SHORT_ADDRESS) |
| { |
| FTDF_Octet *shortAddressPtr = (FTDF_Octet *)&frameHeader->srcAddr.shortAddress; |
| |
| *shortAddressPtr++ = *rxBuffer++; |
| *shortAddressPtr = *rxBuffer++; |
| } |
| else if (srcAddrMode == FTDF_EXTENDED_ADDRESS) |
| { |
| FTDF_Octet *extAddressPtr = (FTDF_Octet *)&frameHeader->srcAddr.extAddress; |
| int n; |
| |
| for (n = 0; n < 8; n++) |
| { |
| *extAddressPtr++ = *rxBuffer++; |
| } |
| } |
| |
| frameHeader->frameType = frameType; |
| frameHeader->options = options; |
| frameHeader->dstAddrMode = dstAddrMode; |
| frameHeader->srcAddrMode = srcAddrMode; |
| |
| return rxBuffer; |
| } |
| |
| #ifndef FTDF_LITE |
| void FTDF_processNextRequest(void) |
| { |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| FTDF_MsgBuffer *request = FTDF_tschGetPending(FTDF_tschSlotLink->request); |
| |
| FTDF_tschSlotLink->request = NULL; |
| |
| FTDF_scheduleTsch(request); |
| |
| return; |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| |
| while (FTDF_reqCurrent == NULL) |
| { |
| FTDF_MsgBuffer *request = FTDF_dequeueReqTail(&FTDF_reqQueue); |
| |
| if (request) |
| { |
| FTDF_processRequest(request); |
| } |
| else |
| { |
| break; |
| } |
| } |
| } |
| #endif /* !FTDF_LITE */ |
| |
| static void processRxFrame(int readBuf) |
| { |
| static FTDF_PANDescriptor PANDescriptor; |
| static FTDF_Address pendAddrList[ 7 ]; |
| |
| FTDF_FrameHeader *frameHeader = &FTDF_fh; |
| #ifndef FTDF_LITE |
| FTDF_SecurityHeader *securityHeader = &FTDF_sh; |
| #endif /* !FTDF_LITE */ |
| |
| uint8_t pendAddrSpec = 0; |
| |
| FTDF_Octet *rxBuffer = |
| (FTDF_Octet *)(IND_R_FTDF_RX_RAM_RX_FIFO + (intptr_t) readBuf * FTDF_BUFFER_LENGTH); |
| FTDF_Octet *rxPtr = rxBuffer; |
| FTDF_DataLength frameLen = *rxPtr++; |
| |
| if (FTDF_transparentMode) |
| { |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.RXSuccessCount++; |
| } |
| |
| uint32_t rxMeta1 = *FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_RX_META_1, (intptr_t)readBuf); |
| FTDF_LinkQuality lqi = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_QUALITY_INDICATOR, readBuf); |
| FTDF_Bitmap32 status = FTDF_TRANSPARENT_RCV_SUCCESSFUL; |
| |
| status |= rxMeta1 & MSK_F_FTDF_RETENTION_RAM_CRC16_ERROR ? FTDF_TRANSPARENT_RCV_CRC_ERROR : 0; |
| status |= rxMeta1 & MSK_F_FTDF_RETENTION_RAM_RES_FRM_TYPE_ERROR ? FTDF_TRANSPARENT_RCV_RES_FRAMETYPE : 0; |
| status |= rxMeta1 & MSK_F_FTDF_RETENTION_RAM_RES_FRM_VERSION_ERROR ? FTDF_TRANSPARENT_RCV_RES_FRAME_VERSION : 0; |
| status |= rxMeta1 & MSK_F_FTDF_RETENTION_RAM_DPANID_ERROR ? FTDF_TRANSPARENT_RCV_UNEXP_DST_PAN_ID : 0; |
| status |= rxMeta1 & MSK_F_FTDF_RETENTION_RAM_DADDR_ERROR ? FTDF_TRANSPARENT_RCV_UNEXP_DST_ADDR : 0; |
| |
| FTDF_RCV_FRAME_TRANSPARENT(frameLen, rxPtr, status, lqi); |
| |
| #if FTDF_TRANSPARENT_USE_WAIT_FOR_ACK |
| |
| if ((FTDF_transparentModeOptions & FTDF_TRANSPARENT_WAIT_FOR_ACK)) |
| { |
| FTDF_getFrameHeader(rxPtr, frameHeader); |
| |
| if (frameHeader->frameType == FTDF_ACKNOWLEDGEMENT_FRAME && |
| (status == FTDF_TRANSPARENT_RCV_SUCCESSFUL)) |
| { |
| |
| #ifndef FTDF_PHY_API |
| volatile uint32_t *txFlagS = FTDF_GET_REG_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_S, FTDF_TX_DATA_BUFFER); |
| |
| while (*txFlagS & MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_STAT) |
| { } |
| |
| // It is required to call FTDF_processTxEvent here because an RX ack generates two events |
| // The RX event is raised first, then after an IFS the TX event is raised. However, |
| // the FTDF_processNextRequest requires that both events have been handled. |
| FTDF_processTxEvent(); |
| #endif /* !FTDF_PHY_API */ |
| |
| FTDF_SN SN = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_MACSN, FTDF_TX_DATA_BUFFER); |
| |
| #ifdef FTDF_PHY_API |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| if (FTDF_txInProgress && |
| frameHeader->SN == SN) |
| { |
| FTDF_exitCritical(); |
| return; |
| } |
| |
| FTDF_exitCritical(); |
| #else |
| |
| if (FTDF_reqCurrent && |
| frameHeader->SN == SN) |
| { |
| FTDF_TransparentRequest *transparentRequest = (FTDF_TransparentRequest *) FTDF_reqCurrent; |
| |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| FTDF_reqCurrent = NULL; |
| FTDF_exitCritical(); |
| FTDF_SEND_FRAME_TRANSPARENT_CONFIRM(transparentRequest->handle, FTDF_TRANSPARENT_SEND_SUCCESSFUL); |
| |
| FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) transparentRequest); |
| |
| return; |
| } |
| |
| #endif /* FTDF_PHY_API */ |
| } |
| } |
| |
| #endif /* FTDF_TRANSPARENT_USE_WAIT_FOR_ACK */ |
| return; |
| } |
| |
| #ifndef FTDF_LITE |
| rxPtr = FTDF_getFrameHeader(rxPtr, frameHeader); |
| |
| #if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_MANUAL |
| |
| if (frameHeader->options & FTDF_OPT_ACK_REQUESTED) |
| { |
| int n; |
| FTDF_Boolean addressFound = FTDF_FALSE; |
| |
| for (n = 0; n < FTDF_NR_OF_REQ_BUFFERS; n++) |
| { |
| if (FTDF_txPendingList[ n ].addrMode == frameHeader->srcAddrMode && |
| FTDF_txPendingList[ n ].PANId == frameHeader->srcPANId) |
| { |
| if (frameHeader->srcAddrMode == FTDF_SHORT_ADDRESS) |
| { |
| if (FTDF_txPendingList[ n ].addr.shortAddress == |
| frameHeader->srcAddr.shortAddress) |
| { |
| addressFound = FTDF_TRUE; |
| break; |
| } |
| } |
| else if (frameHeader->srcAddrMode == FTDF_EXTENDED_ADDRESS) |
| { |
| if (FTDF_txPendingList[ n ].addr.extAddress == |
| frameHeader->srcAddr.extAddress) |
| { |
| addressFound = FTDF_TRUE; |
| break; |
| } |
| } |
| else |
| { |
| // Invalid srcAddrMode |
| return; |
| } |
| } |
| } |
| |
| if (addressFound) |
| { |
| FTDF_fpprSetMode(FTDF_FALSE, FTDF_TRUE, FTDF_TRUE); |
| } |
| else |
| { |
| FTDF_fpprSetMode(FTDF_FALSE, FTDF_TRUE, FTDF_FALSE); |
| } |
| } |
| |
| #endif |
| |
| if (frameHeader->frameVersion == FTDF_FRAME_VERSION_NOT_SUPPORTED) |
| { |
| return; |
| } |
| |
| #if defined(FTDF_NO_CSL) && defined(FTDF_NO_TSCH) |
| else if (frameHeader->frameVersion == FTDF_FRAME_VERSION_E || |
| frameHeader->frameType == FTDF_MULTIPURPOSE_FRAME) |
| { |
| return; |
| } |
| |
| #endif /* FTDF_NO_CSL && FTDF_NO_TSCH */ |
| |
| FTDF_FrameType frameType = frameHeader->frameType; |
| FTDF_Boolean duplicate = FTDF_FALSE; |
| |
| if ((frameHeader->options & FTDF_OPT_SEQ_NR_SUPPRESSED) == 0 && |
| frameHeader->srcAddrMode != FTDF_NO_ADDRESS) |
| { |
| FTDF_Time timestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_RX_TIMESTAMP, readBuf); |
| FTDF_SNSel snSel = FTDF_SN_SEL_DSN; |
| FTDF_Boolean drop; |
| |
| if ((FTDF_pib.tschEnabled || frameHeader->frameVersion == FTDF_FRAME_VERSION_E) && |
| (frameHeader->options & FTDF_OPT_ACK_REQUESTED)) |
| { |
| drop = FTDF_FALSE; |
| } |
| else |
| { |
| drop = FTDF_TRUE; |
| } |
| |
| if (frameType == FTDF_BEACON_FRAME) |
| { |
| snSel = frameHeader->frameVersion == FTDF_FRAME_VERSION_E ? FTDF_SN_SEL_EBSN : FTDF_SN_SEL_BSN; |
| } |
| |
| uint8_t i; |
| |
| for (i = 0; i < FTDF_NR_OF_RX_ADDRS; i++) |
| { |
| // Check if entry is empty or matches |
| if (FTDF_rxa[ i ].addrMode == FTDF_NO_ADDRESS || |
| (FTDF_rxa[ i ].addrMode == frameHeader->srcAddrMode && |
| ((frameHeader->srcAddrMode == FTDF_SHORT_ADDRESS && |
| frameHeader->srcAddr.shortAddress == FTDF_rxa[ i ].addr.shortAddress) || |
| (frameHeader->srcAddrMode == FTDF_EXTENDED_ADDRESS && |
| frameHeader->srcAddr.extAddress == FTDF_rxa[ i ].addr.extAddress)))) |
| { |
| break; |
| } |
| } |
| |
| if (i < FTDF_NR_OF_RX_ADDRS) |
| { |
| if (FTDF_rxa[ i ].addrMode != FTDF_NO_ADDRESS) |
| { |
| switch (snSel) |
| { |
| case FTDF_SN_SEL_DSN: |
| |
| if (FTDF_rxa[ i ].dsnValid == FTDF_TRUE) |
| { |
| if (frameHeader->SN == FTDF_rxa[ i ].dsn) |
| { |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.duplicateFrameCount++; |
| } |
| |
| if (drop) |
| { |
| return; |
| } |
| |
| duplicate = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| FTDF_rxa[ i ].dsnValid = FTDF_TRUE; |
| } |
| |
| FTDF_rxa[ i ].dsn = frameHeader->SN; |
| break; |
| |
| case FTDF_SN_SEL_BSN: |
| |
| if (FTDF_rxa[ i ].bsnValid == FTDF_TRUE) |
| { |
| if (frameHeader->SN == FTDF_rxa[ i ].bsn) |
| { |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.duplicateFrameCount++; |
| } |
| |
| if (drop) |
| { |
| return; |
| } |
| |
| duplicate = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| FTDF_rxa[ i ].bsnValid = FTDF_TRUE; |
| } |
| |
| FTDF_rxa[ i ].bsn = frameHeader->SN; |
| break; |
| |
| case FTDF_SN_SEL_EBSN: |
| |
| if (FTDF_rxa[ i ].ebsnValid == FTDF_TRUE) |
| { |
| if (frameHeader->SN == FTDF_rxa[ i ].ebsn) |
| { |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.duplicateFrameCount++; |
| } |
| |
| if (drop) |
| { |
| return; |
| } |
| |
| duplicate = FTDF_TRUE; |
| } |
| } |
| else |
| { |
| FTDF_rxa[ i ].ebsnValid = FTDF_TRUE; |
| } |
| |
| FTDF_rxa[ i ].ebsn = frameHeader->SN; |
| break; |
| } |
| } |
| else |
| { |
| FTDF_rxa[ i ].addrMode = frameHeader->srcAddrMode; |
| FTDF_rxa[ i ].addr = frameHeader->srcAddr; |
| |
| switch (snSel) |
| { |
| case FTDF_SN_SEL_DSN: |
| FTDF_rxa[ i ].dsnValid = FTDF_TRUE; |
| FTDF_rxa[ i ].dsn = frameHeader->SN; |
| break; |
| |
| case FTDF_SN_SEL_BSN: |
| FTDF_rxa[ i ].bsnValid = FTDF_TRUE; |
| FTDF_rxa[ i ].bsn = frameHeader->SN; |
| break; |
| |
| case FTDF_SN_SEL_EBSN: |
| FTDF_rxa[ i ].ebsnValid = FTDF_TRUE; |
| FTDF_rxa[ i ].ebsn = frameHeader->SN; |
| break; |
| } |
| } |
| |
| FTDF_rxa[ i ].timestamp = timestamp; |
| } |
| else |
| { |
| // find oldest entry and overwrite it |
| FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| FTDF_Time delta, greatestDelta = 0; |
| uint8_t entry = 0; |
| |
| for (i = 0; i < FTDF_NR_OF_RX_ADDRS; i++) |
| { |
| delta = curTime - FTDF_rxa[ i ].timestamp; |
| |
| if (delta > greatestDelta) |
| { |
| greatestDelta = delta; |
| entry = i; |
| } |
| } |
| |
| FTDF_rxa[ entry ].addrMode = frameHeader->srcAddrMode; |
| FTDF_rxa[ entry ].addr = frameHeader->srcAddr; |
| |
| switch (snSel) |
| { |
| case FTDF_SN_SEL_DSN: |
| FTDF_rxa[ entry ].bsnValid = FTDF_FALSE; |
| FTDF_rxa[ entry ].ebsnValid = FTDF_FALSE; |
| FTDF_rxa[ entry ].dsnValid = FTDF_TRUE; |
| FTDF_rxa[ entry ].dsn = frameHeader->SN; |
| break; |
| |
| case FTDF_SN_SEL_BSN: |
| FTDF_rxa[ entry ].dsnValid = FTDF_FALSE; |
| FTDF_rxa[ entry ].ebsnValid = FTDF_FALSE; |
| FTDF_rxa[ entry ].bsnValid = FTDF_TRUE; |
| FTDF_rxa[ entry ].bsn = frameHeader->SN; |
| break; |
| |
| case FTDF_SN_SEL_EBSN: |
| FTDF_rxa[ entry ].dsnValid = FTDF_FALSE; |
| FTDF_rxa[ entry ].bsnValid = FTDF_FALSE; |
| FTDF_rxa[ entry ].ebsnValid = FTDF_TRUE; |
| FTDF_rxa[ entry ].ebsn = frameHeader->SN; |
| break; |
| } |
| } |
| } |
| |
| if (frameHeader->options & FTDF_OPT_SECURITY_ENABLED) |
| { |
| rxPtr = FTDF_getSecurityHeader(rxPtr, frameHeader->frameVersion, securityHeader); |
| } |
| else |
| { |
| securityHeader->securityLevel = 0; |
| securityHeader->keyIdMode = 0; |
| } |
| |
| FTDF_IEList *headerIEList = NULL; |
| FTDF_IEList *payloadIEList = NULL; |
| int micLength = FTDF_getMicLength(securityHeader->securityLevel); |
| |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| |
| if (frameHeader->options & FTDF_OPT_IES_PRESENT) |
| { |
| rxPtr = |
| FTDF_getIes(rxPtr, rxBuffer + (frameLen - micLength - FTDF_FCS_LENGTH), &headerIEList, &payloadIEList); |
| } |
| |
| #endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */ |
| |
| // Get start of private data (needed to unsecure a frame) |
| if (frameType == FTDF_MAC_COMMAND_FRAME) |
| { |
| frameHeader->commandFrameId = *rxPtr++; |
| } |
| else if (frameType == FTDF_BEACON_FRAME) |
| { |
| PANDescriptor.coordAddrMode = frameHeader->srcAddrMode; |
| PANDescriptor.coordPANId = frameHeader->srcPANId; |
| PANDescriptor.coordAddr = frameHeader->srcAddr; |
| PANDescriptor.channelNumber = ((FTDF_GET_FIELD(ON_OFF_REGMAP_PHYRXATTR) >> 4) & 0xf) + 11; |
| PANDescriptor.channelPage = 0; |
| PANDescriptor.timestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_RX_TIMESTAMP, readBuf); |
| PANDescriptor.linkQuality = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_QUALITY_INDICATOR, readBuf); |
| |
| FTDF_Octet *superframeSpecPtr = (FTDF_Octet *) &PANDescriptor.superframeSpec; |
| *superframeSpecPtr++ = *rxPtr++; |
| *superframeSpecPtr = *rxPtr++; |
| |
| uint8_t gtsSpec = *rxPtr++; |
| |
| PANDescriptor.GTSPermit = (gtsSpec & 0x08) ? FTDF_TRUE : FTDF_FALSE; |
| uint8_t gtsDescrCount = gtsSpec & 0x7; |
| |
| if (gtsDescrCount != 0) |
| { |
| // GTS is not supported, so just skip the GTS direction and GTS list fields if present |
| rxPtr += (1 + (3 * gtsDescrCount)); |
| } |
| |
| pendAddrSpec = *rxPtr++; |
| uint8_t nrOfShortAddrs = pendAddrSpec & 0x07; |
| uint8_t nrOfExtAddrs = (pendAddrSpec & 0x70) >> 4; |
| |
| int n; |
| |
| for (n = 0; n < (nrOfShortAddrs + nrOfExtAddrs); n++) |
| { |
| if (n < nrOfShortAddrs) |
| { |
| FTDF_Octet *shortAddressPtr = (FTDF_Octet *) &pendAddrList[ n ].shortAddress; |
| *shortAddressPtr++ = *rxBuffer++; |
| *shortAddressPtr = *rxBuffer++; |
| } |
| else |
| { |
| FTDF_Octet *extAddressPtr = (FTDF_Octet *) &pendAddrList[ n ].extAddress; |
| int m; |
| |
| for (m = 0; m < 8; m++) |
| { |
| *extAddressPtr++ = *rxBuffer++; |
| } |
| } |
| } |
| } |
| else if (frameType == FTDF_ACKNOWLEDGEMENT_FRAME && |
| securityHeader->securityLevel != 0) |
| { |
| if (FTDF_reqCurrent) |
| { |
| switch (FTDF_reqCurrent->msgId) |
| { |
| case FTDF_DATA_REQUEST: |
| { |
| FTDF_DataRequest *dataRequest = (FTDF_DataRequest *) FTDF_reqCurrent; |
| frameHeader->srcPANId = dataRequest->dstPANId; |
| frameHeader->srcAddrMode = dataRequest->dstAddrMode; |
| frameHeader->srcAddr = dataRequest->dstAddr; |
| break; |
| } |
| |
| case FTDF_POLL_REQUEST: |
| { |
| FTDF_PollRequest *pollRequest = (FTDF_PollRequest *) FTDF_reqCurrent; |
| frameHeader->srcPANId = pollRequest->coordPANId; |
| frameHeader->srcAddrMode = pollRequest->coordAddrMode; |
| frameHeader->srcAddr = pollRequest->coordAddr; |
| break; |
| } |
| |
| case FTDF_ASSOCIATE_REQUEST: |
| { |
| FTDF_AssociateRequest *associateRequest = (FTDF_AssociateRequest *) FTDF_reqCurrent; |
| frameHeader->srcPANId = associateRequest->coordPANId; |
| frameHeader->srcAddrMode = associateRequest->coordAddrMode; |
| frameHeader->srcAddr = associateRequest->coordAddr; |
| break; |
| } |
| |
| case FTDF_DISASSOCIATE_REQUEST: |
| { |
| FTDF_DisassociateRequest *disassociateRequest = |
| (FTDF_DisassociateRequest *) FTDF_reqCurrent; |
| frameHeader->srcPANId = disassociateRequest->devicePANId; |
| frameHeader->srcAddrMode = disassociateRequest->deviceAddrMode; |
| frameHeader->srcAddr = disassociateRequest->deviceAddress; |
| break; |
| } |
| |
| case FTDF_ASSOCIATE_RESPONSE: |
| { |
| FTDF_AssociateResponse *associateResponse = (FTDF_AssociateResponse *) FTDF_reqCurrent; |
| frameHeader->srcAddrMode = FTDF_EXTENDED_ADDRESS; |
| frameHeader->srcAddr.extAddress = associateResponse->deviceAddress; |
| break; |
| } |
| } |
| } |
| } |
| |
| FTDF_Status status = FTDF_unsecureFrame(rxBuffer, rxPtr, frameHeader, securityHeader); |
| |
| if (status != FTDF_SUCCESS) |
| { |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.securityFailureCount++; |
| } |
| |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| |
| // Since unsecure of acknowledgement frame is always successful, |
| // nothing special has to be done to get the address information correct. |
| FTDF_sendCommStatusIndication(FTDF_reqCurrent, status, |
| FTDF_pib.PANId, |
| frameHeader->srcAddrMode, |
| frameHeader->srcAddr, |
| frameHeader->dstAddrMode, |
| frameHeader->dstAddr, |
| securityHeader->securityLevel, |
| securityHeader->keyIdMode, |
| securityHeader->keySource, |
| securityHeader->keyIndex); |
| |
| if (frameType == FTDF_ACKNOWLEDGEMENT_FRAME && FTDF_reqCurrent) |
| { |
| sendConfirm(FTDF_NO_ACK, |
| FTDF_reqCurrent->msgId); |
| |
| FTDF_processNextRequest(); |
| } |
| |
| return; |
| } |
| |
| if (FTDF_pib.metricsEnabled && frameType != FTDF_ACKNOWLEDGEMENT_FRAME) |
| { |
| FTDF_pib.performanceMetrics.RXSuccessCount++; |
| } |
| |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled && frameType != FTDF_ACKNOWLEDGEMENT_FRAME) |
| { |
| FTDF_Time timestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_RX_TIMESTAMP, readBuf); |
| |
| FTDF_correctSlotTime(timestamp); |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| |
| switch (frameType) |
| { |
| case FTDF_ACKNOWLEDGEMENT_FRAME: |
| |
| if (FTDF_pib.metricsEnabled) |
| { |
| if (FTDF_nrOfRetries == 0) |
| { |
| FTDF_pib.performanceMetrics.TXSuccessCount++; |
| } |
| else if (FTDF_nrOfRetries == 1) |
| { |
| FTDF_pib.performanceMetrics.retryCount++; |
| } |
| else |
| { |
| FTDF_pib.performanceMetrics.multipleRetryCount++; |
| } |
| } |
| |
| if (frameHeader->frameVersion == FTDF_FRAME_VERSION_E) |
| { |
| FTDF_pib.trafficCounters.rxEnhAckFrmOkCnt++; |
| } |
| |
| break; |
| |
| case FTDF_BEACON_FRAME: |
| FTDF_pib.trafficCounters.rxBeaconFrmOkCnt++; |
| break; |
| |
| case FTDF_DATA_FRAME: |
| FTDF_pib.trafficCounters.rxDataFrmOkCnt++; |
| break; |
| |
| case FTDF_MAC_COMMAND_FRAME: |
| FTDF_pib.trafficCounters.rxCmdFrmOkCnt++; |
| break; |
| |
| case FTDF_MULTIPURPOSE_FRAME: |
| FTDF_pib.trafficCounters.rxMultiPurpFrmOkCnt++; |
| break; |
| } |
| |
| if (frameType == FTDF_ACKNOWLEDGEMENT_FRAME) |
| { |
| volatile uint32_t *txFlagS = FTDF_GET_REG_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_S, FTDF_TX_DATA_BUFFER); |
| |
| while (*txFlagS & MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_STAT) |
| { } |
| |
| // It is required to call FTDF_processTxEvent here because an RX ack generates two events |
| // The RX event is raised first, then after an IFS the TX event is raised. However, |
| // the FTDF_processNextRequest requires that both events have been handled. |
| FTDF_processTxEvent(); |
| |
| FTDF_SN SN = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_MACSN, FTDF_TX_DATA_BUFFER); |
| |
| if (FTDF_reqCurrent && |
| frameHeader->SN == SN) |
| { |
| #ifndef FTDF_NO_CSL |
| |
| if (FTDF_pib.leEnabled == FTDF_TRUE) |
| { |
| FTDF_Time timestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_RX_TIMESTAMP, |
| readBuf); |
| |
| FTDF_setPeerCslTiming(headerIEList, timestamp); |
| } |
| |
| #endif /* FTDF_NO_CSL */ |
| |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled == FTDF_TRUE) |
| { |
| FTDF_correctSlotTimeFromAck(headerIEList); |
| |
| FTDF_TschRetry *tschRetry = FTDF_getTschRetry(FTDF_getRequestAddress(FTDF_reqCurrent)); |
| |
| tschRetry->nrOfRetries = 0; |
| FTDF_tschSlotLink->request = NULL; |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| |
| switch (FTDF_reqCurrent->msgId) |
| { |
| case FTDF_DATA_REQUEST: |
| { |
| FTDF_Time timestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_TXTIMESTAMP, |
| FTDF_TX_DATA_BUFFER); |
| FTDF_NumOfBackoffs numOfBackoffs = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_CSMACANRRETRIES, |
| FTDF_TX_DATA_BUFFER); |
| |
| FTDF_sendDataConfirm((FTDF_DataRequest *)FTDF_reqCurrent, |
| FTDF_SUCCESS, |
| timestamp, |
| SN, |
| numOfBackoffs, |
| payloadIEList); |
| |
| break; |
| } |
| |
| case FTDF_POLL_REQUEST: |
| { |
| if (!(frameHeader->options & FTDF_OPT_FRAME_PENDING)) |
| { |
| FTDF_sendPollConfirm((FTDF_PollRequest *)FTDF_reqCurrent, FTDF_NO_DATA); |
| } |
| |
| break; |
| } |
| |
| case FTDF_ASSOCIATE_REQUEST: |
| { |
| FTDF_AssocAdmin *assocAdmin = &FTDF_aa; |
| |
| if (assocAdmin->fastA == FTDF_TRUE || |
| assocAdmin->dataR == FTDF_FALSE) |
| { |
| uint32_t timestamp = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYMBOLTIME2THR, |
| (timestamp + FTDF_pib.responseWaitTime * FTDF_BASE_SUPERFRAME_DURATION)); |
| } |
| else if (!(frameHeader->options & FTDF_OPT_FRAME_PENDING)) |
| { |
| FTDF_sendAssociateConfirm((FTDF_AssociateRequest *)FTDF_reqCurrent, |
| FTDF_NO_DATA, |
| 0xffff); |
| } |
| |
| break; |
| } |
| |
| case FTDF_ASSOCIATE_RESPONSE: |
| { |
| FTDF_AssociateResponse *assocResp = (FTDF_AssociateResponse *)FTDF_reqCurrent; |
| |
| FTDF_Address srcAddr, dstAddr; |
| srcAddr.extAddress = FTDF_pib.extAddress; |
| dstAddr.extAddress = assocResp->deviceAddress; |
| |
| FTDF_sendCommStatusIndication(FTDF_reqCurrent, FTDF_SUCCESS, |
| FTDF_pib.PANId, |
| FTDF_EXTENDED_ADDRESS, |
| srcAddr, |
| FTDF_EXTENDED_ADDRESS, |
| dstAddr, |
| assocResp->securityLevel, |
| assocResp->keyIdMode, |
| assocResp->keySource, |
| assocResp->keyIndex); |
| break; |
| } |
| |
| case FTDF_ORPHAN_RESPONSE: |
| { |
| FTDF_OrphanResponse *orphanResp = (FTDF_OrphanResponse *)FTDF_reqCurrent; |
| |
| FTDF_Address srcAddr, dstAddr; |
| srcAddr.extAddress = FTDF_pib.extAddress; |
| dstAddr.extAddress = orphanResp->orphanAddress; |
| |
| FTDF_sendCommStatusIndication(FTDF_reqCurrent, FTDF_SUCCESS, |
| FTDF_pib.PANId, |
| FTDF_EXTENDED_ADDRESS, |
| srcAddr, |
| FTDF_EXTENDED_ADDRESS, |
| dstAddr, |
| orphanResp->securityLevel, |
| orphanResp->keyIdMode, |
| orphanResp->keySource, |
| orphanResp->keyIndex); |
| break; |
| } |
| |
| case FTDF_DISASSOCIATE_REQUEST: |
| { |
| FTDF_sendDisassociateConfirm((FTDF_DisassociateRequest *)FTDF_reqCurrent, FTDF_SUCCESS); |
| break; |
| } |
| |
| case FTDF_REMOTE_REQUEST: |
| { |
| FTDF_RemoteRequest *remoteRequest = (FTDF_RemoteRequest *) FTDF_reqCurrent; |
| |
| if (remoteRequest->remoteId == FTDF_REMOTE_PAN_ID_CONFLICT_NOTIFICATION) |
| { |
| FTDF_sendSyncLossIndication(FTDF_PAN_ID_CONFLICT, securityHeader); |
| } |
| |
| FTDF_reqCurrent = NULL; |
| |
| break; |
| } |
| } |
| |
| if (FTDF_reqCurrent->msgId != FTDF_DATA_REQUEST) |
| { |
| // for data request the application owns the memory |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| } |
| |
| FTDF_processNextRequest(); |
| } |
| else |
| { |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| } |
| } |
| else if ((frameHeader->frameVersion == FTDF_FRAME_VERSION_E || FTDF_pib.tschEnabled) && |
| (frameHeader->options & FTDF_OPT_ACK_REQUESTED)) |
| { |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| static FTDF_FrameHeader afh; |
| FTDF_FrameHeader *ackFrameHeader = &afh; |
| |
| ackFrameHeader->frameType = FTDF_ACKNOWLEDGEMENT_FRAME; |
| ackFrameHeader->options = |
| (frameHeader->options & |
| (FTDF_OPT_SECURITY_ENABLED | FTDF_OPT_SEQ_NR_SUPPRESSED)) | FTDF_OPT_ENHANCED; |
| |
| if (FTDF_pib.leEnabled == FTDF_TRUE || |
| FTDF_pib.tschEnabled == FTDF_TRUE || |
| FTDF_pib.EAckIEList.nrOfIEs != 0) |
| { |
| ackFrameHeader->options |= FTDF_OPT_IES_PRESENT; |
| } |
| |
| ackFrameHeader->dstAddrMode = FTDF_NO_ADDRESS; |
| ackFrameHeader->srcAddrMode = FTDF_NO_ADDRESS; |
| ackFrameHeader->SN = frameHeader->SN; |
| |
| FTDF_Octet *txPtr = (FTDF_Octet *) FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO) + |
| (FTDF_BUFFER_LENGTH * FTDF_TX_ACK_BUFFER); |
| |
| // Skip PHY header (= MAC length) |
| txPtr++; |
| |
| txPtr = FTDF_addFrameHeader(txPtr, |
| ackFrameHeader, |
| 0); |
| |
| if (frameHeader->options & FTDF_OPT_SECURITY_ENABLED) |
| { |
| securityHeader->frameCounter = FTDF_pib.frameCounter; |
| securityHeader->frameCounterMode = FTDF_pib.frameCounterMode; |
| |
| txPtr = FTDF_addSecurityHeader(txPtr, |
| securityHeader); |
| } |
| |
| #ifndef FTDF_NO_CSL |
| |
| if (FTDF_pib.leEnabled == FTDF_TRUE) |
| { |
| static FTDF_Octet phaseAndPeriod[ 4 ]; |
| static FTDF_IEDescriptor cslIE = { 0x1a, 4, { phaseAndPeriod } }; |
| static FTDF_IEList cslIEList = { 1, &cslIE }; |
| FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| |
| FTDF_Time delta = curTime - |
| (FTDF_startCslSampleTime - FTDF_pib.CSLPeriod * 10); |
| |
| *(FTDF_Period *)(phaseAndPeriod + 0) = (FTDF_Period)(delta / 10); |
| *(FTDF_Period *)(phaseAndPeriod + 2) = FTDF_pib.CSLPeriod; |
| |
| txPtr = FTDF_addIes(txPtr, |
| &cslIEList, |
| &FTDF_pib.EAckIEList, |
| FTDF_FALSE); |
| } |
| |
| #endif /* FTDF_NO_CSL */ |
| |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled == FTDF_TRUE) |
| { |
| FTDF_Time rxTimestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_RX_TIMESTAMP, readBuf); |
| |
| txPtr = FTDF_addCorrTimeIE(txPtr, rxTimestamp); |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| |
| if (!FTDF_pib.leEnabled && !FTDF_pib.tschEnabled) |
| { |
| txPtr = FTDF_addIes(txPtr, |
| NULL, |
| &FTDF_pib.EAckIEList, |
| FTDF_FALSE); |
| } |
| |
| FTDF_sendAckFrame(frameHeader, |
| securityHeader, |
| txPtr); |
| #endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */ |
| |
| if (duplicate) |
| { |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| return; |
| } |
| } |
| |
| if (frameType == FTDF_DATA_FRAME || frameType == FTDF_MULTIPURPOSE_FRAME) |
| { |
| FTDF_DataLength payloadLength = frameLen - |
| (rxPtr - rxBuffer) + 1 - micLength - FTDF_FCS_LENGTH; |
| |
| if (FTDF_reqCurrent && |
| FTDF_reqCurrent->msgId == FTDF_POLL_REQUEST) |
| { |
| FTDF_PollRequest *pollRequest = (FTDF_PollRequest *) FTDF_reqCurrent; |
| |
| if (frameHeader->srcAddrMode == pollRequest->coordAddrMode && |
| frameHeader->srcPANId == pollRequest->coordPANId && |
| ((frameHeader->srcAddrMode == FTDF_SHORT_ADDRESS && |
| frameHeader->srcAddr.shortAddress == pollRequest->coordAddr.shortAddress) || |
| (frameHeader->srcAddrMode == FTDF_EXTENDED_ADDRESS && |
| frameHeader->srcAddr.extAddress == pollRequest->coordAddr.extAddress))) |
| { |
| if (payloadLength == 0) |
| { |
| FTDF_sendPollConfirm(pollRequest, FTDF_NO_DATA); |
| } |
| else |
| { |
| FTDF_sendPollConfirm(pollRequest, FTDF_SUCCESS); |
| } |
| } |
| } |
| else if (FTDF_reqCurrent && |
| FTDF_reqCurrent->msgId == FTDF_ASSOCIATE_REQUEST && |
| payloadLength == 0) |
| { |
| sendConfirm(FTDF_NO_DATA, FTDF_ASSOCIATE_REQUEST); |
| } |
| |
| if (payloadLength != 0) |
| { |
| FTDF_LinkQuality mpduLinkQuality = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_QUALITY_INDICATOR, |
| readBuf); |
| FTDF_Time timestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_RX_TIMESTAMP, |
| readBuf); |
| |
| FTDF_sendDataIndication(frameHeader, |
| securityHeader, |
| payloadIEList, |
| payloadLength, |
| rxPtr, |
| mpduLinkQuality, |
| timestamp); |
| } |
| |
| #ifndef FTDF_NO_CSL |
| else if (headerIEList->nrOfIEs == 1 && |
| headerIEList->IEs[ 0 ].ID == 0x1d) |
| { |
| FTDF_Period rzTime = *(uint16_t *) headerIEList->IEs[ 0 ].content.raw; |
| |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| |
| FTDF_rzTime = curTime + (FTDF_Time) rzTime * 10 + 260; // 260 length of max frame in symbols |
| |
| FTDF_Time CSLPeriod = FTDF_pib.CSLPeriod * 10; |
| FTDF_Time delta = FTDF_rzTime - FTDF_startCslSampleTime; |
| |
| while (delta < 0x80000000) // A delta larger than 0x80000000 is assumed a negative delta |
| { |
| FTDF_startCslSampleTime += CSLPeriod; |
| delta = FTDF_rzTime - FTDF_startCslSampleTime; |
| } |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLSTARTSAMPLETIME, FTDF_startCslSampleTime); |
| |
| FTDF_exitCritical(); |
| |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| } |
| |
| #endif /* FTDF_NO_CSL */ |
| else |
| { |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| } |
| } |
| else if (frameType == FTDF_MAC_COMMAND_FRAME) |
| { |
| FTDF_processCommandFrame(rxPtr, frameHeader, securityHeader, payloadIEList); |
| } |
| else if (frameType == FTDF_BEACON_FRAME) |
| { |
| FTDF_Octet *superframeSpecPtr = (FTDF_Octet *)&PANDescriptor.superframeSpec; |
| superframeSpecPtr++; |
| |
| if (FTDF_isPANCoordinator) |
| { |
| if (frameHeader->srcPANId == FTDF_pib.PANId && (*superframeSpecPtr & 0x40)) |
| { |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| FTDF_sendSyncLossIndication(FTDF_PAN_ID_CONFLICT, securityHeader); |
| return; |
| } |
| } |
| else if (FTDF_pib.associatedPANCoord) |
| { |
| if (frameHeader->srcPANId == FTDF_pib.PANId && (*superframeSpecPtr & 0x40) && |
| ((frameHeader->srcAddrMode == FTDF_SHORT_ADDRESS && |
| frameHeader->srcAddr.shortAddress != FTDF_pib.coordShortAddress) || |
| (frameHeader->srcAddrMode == FTDF_EXTENDED_ADDRESS && |
| frameHeader->srcAddr.extAddress != FTDF_pib.coordExtAddress))) |
| { |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| FTDF_sendPANIdConflictNotification(frameHeader, securityHeader); |
| return; |
| } |
| } |
| |
| FTDF_DataLength beaconPayloadLength = frameLen - (rxPtr - rxBuffer) + 1 - micLength - FTDF_FCS_LENGTH; |
| |
| if (FTDF_pib.autoRequest == FTDF_FALSE || |
| beaconPayloadLength != 0) |
| { |
| FTDF_Time timestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_RX_TIMESTAMP, |
| readBuf); |
| |
| FTDF_BeaconNotifyIndication *beaconNotifyIndication = |
| (FTDF_BeaconNotifyIndication *) FTDF_GET_MSG_BUFFER( |
| sizeof(FTDF_BeaconNotifyIndication)); |
| |
| beaconNotifyIndication->msgId = FTDF_BEACON_NOTIFY_INDICATION; |
| beaconNotifyIndication->BSN = frameHeader->SN; |
| beaconNotifyIndication->PANDescriptor = &PANDescriptor; |
| beaconNotifyIndication->pendAddrSpec = pendAddrSpec; |
| beaconNotifyIndication->addrList = pendAddrList; |
| beaconNotifyIndication->sduLength = beaconPayloadLength; |
| beaconNotifyIndication->sdu = FTDF_GET_DATA_BUFFER(beaconPayloadLength); |
| beaconNotifyIndication->EBSN = frameHeader->SN; |
| beaconNotifyIndication->beaconType = |
| frameHeader->frameVersion == FTDF_FRAME_VERSION_E ? FTDF_ENHANCED_BEACON : FTDF_NORMAL_BEACON; |
| beaconNotifyIndication->IEList = payloadIEList; |
| beaconNotifyIndication->timestamp = timestamp; |
| |
| memcpy(beaconNotifyIndication->sdu, rxPtr, beaconPayloadLength); |
| |
| FTDF_RCV_MSG((FTDF_MsgBuffer *) beaconNotifyIndication); |
| } |
| else if (FTDF_reqCurrent && |
| FTDF_reqCurrent->msgId == FTDF_SCAN_REQUEST) |
| { |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| FTDF_addPANdescriptor(&PANDescriptor); |
| } |
| else |
| { |
| FTDF_REL_DATA_BUFFER((FTDF_Octet *)payloadIEList); |
| } |
| } |
| |
| #if FTDF_USE_LPDP |
| #if FTDF_FP_BIT_TEST_MODE |
| |
| if (FTDF_lpdpIsEnabled() && !FTDF_reqCurrent && frameType == FTDF_DATA_FRAME) |
| { |
| FTDF_processTxPending(frameHeader, securityHeader); |
| } |
| |
| #else /* FTDF_FP_BIT_TEST_MODE */ |
| |
| if (!FTDF_reqCurrent && frameType == FTDF_DATA_FRAME) |
| { |
| FTDF_processTxPending(frameHeader, securityHeader); |
| } |
| |
| #endif /* FTDF_FP_BIT_TEST_MODE */ |
| #endif /* FTDF_USE_LPDP */ |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled == FTDF_TRUE) |
| { |
| FTDF_scheduleTsch(NULL); |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| } |
| |
| |
| |
| void FTDF_processRxEvent(void) |
| { |
| volatile uint32_t *rxEvent = (volatile uint32_t *) IND_R_FTDF_ON_OFF_REGMAP_RX_EVENT; |
| |
| if (*rxEvent & MSK_F_FTDF_ON_OFF_REGMAP_RXSOF_E) |
| { |
| #ifdef SIMULATOR |
| *rxEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_RXSOF_E; |
| #else |
| *rxEvent = MSK_F_FTDF_ON_OFF_REGMAP_RXSOF_E; |
| #endif |
| } |
| |
| if (*rxEvent & MSK_F_FTDF_ON_OFF_REGMAP_RXBYTE_E) |
| { |
| #ifdef SIMULATOR |
| *rxEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_RXBYTE_E; |
| #else |
| *rxEvent = MSK_F_FTDF_ON_OFF_REGMAP_RXBYTE_E; |
| #endif |
| } |
| |
| if (*rxEvent & MSK_F_FTDF_ON_OFF_REGMAP_RX_OVERFLOW_E) |
| { |
| // No API defined to report this error to the higher layer, so just clear it. |
| #ifdef SIMULATOR |
| *rxEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_RX_OVERFLOW_E; |
| #else |
| *rxEvent = MSK_F_FTDF_ON_OFF_REGMAP_RX_OVERFLOW_E; |
| #endif |
| } |
| |
| if (*rxEvent & MSK_F_FTDF_ON_OFF_REGMAP_RX_BUF_AVAIL_E) |
| { |
| int readBuf = FTDF_GET_FIELD(ON_OFF_REGMAP_RX_READ_BUF_PTR); |
| int writeBuf = FTDF_GET_FIELD(ON_OFF_REGMAP_RX_WRITE_BUF_PTR); |
| |
| while (readBuf != writeBuf) |
| { |
| processRxFrame(readBuf % 8); |
| readBuf = (readBuf + 1) % 16; |
| } |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RX_READ_BUF_PTR, readBuf); |
| |
| #ifdef SIMULATOR |
| *rxEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_RX_BUF_AVAIL_E; |
| #else |
| *rxEvent = MSK_F_FTDF_ON_OFF_REGMAP_RX_BUF_AVAIL_E; |
| #endif |
| } |
| |
| volatile uint32_t *lmacEvent = (volatile uint32_t *) IND_R_FTDF_ON_OFF_REGMAP_LMAC_EVENT; |
| |
| if (*lmacEvent & MSK_F_FTDF_ON_OFF_REGMAP_EDSCANREADY_E) |
| { |
| #ifdef SIMULATOR |
| *lmacEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_EDSCANREADY_E; |
| #else |
| *lmacEvent = MSK_F_FTDF_ON_OFF_REGMAP_EDSCANREADY_E; |
| #endif |
| |
| #ifndef FTDF_LITE |
| FTDF_MsgBuffer *request = FTDF_reqCurrent; |
| |
| if (request->msgId == FTDF_SCAN_REQUEST) |
| { |
| FTDF_scanReady((FTDF_ScanRequest *) request); |
| } |
| |
| #endif /* !FTDF_LITE */ |
| } |
| |
| if (*lmacEvent & MSK_F_FTDF_ON_OFF_REGMAP_RXTIMEREXPIRED_E) |
| { |
| #ifdef SIMULATOR |
| *lmacEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_RXTIMEREXPIRED_E; |
| #else |
| *lmacEvent = MSK_F_FTDF_ON_OFF_REGMAP_RXTIMEREXPIRED_E; |
| #endif |
| |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.RxExpiredCount++; |
| } |
| |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| FTDF_scheduleTsch(NULL); |
| } |
| else |
| #endif /* FTDF_NO_TSCH */ |
| if (FTDF_reqCurrent) |
| { |
| FTDF_MsgId msgId = FTDF_reqCurrent->msgId; |
| |
| if (msgId == FTDF_POLL_REQUEST) |
| { |
| FTDF_sendPollConfirm((FTDF_PollRequest *)FTDF_reqCurrent, FTDF_NO_DATA); |
| } |
| else if (msgId == FTDF_SCAN_REQUEST) |
| { |
| FTDF_scanReady((FTDF_ScanRequest *) FTDF_reqCurrent); |
| } |
| else if (msgId == FTDF_ASSOCIATE_REQUEST) |
| { |
| FTDF_sendAssociateConfirm((FTDF_AssociateRequest *)FTDF_reqCurrent, |
| FTDF_NO_DATA, |
| 0xffff); |
| } |
| } |
| |
| #endif /* !FTDF_LITE */ |
| } |
| |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| |
| if (*lmacEvent & MSK_F_FTDF_ON_OFF_REGMAP_CSMA_CA_BO_THR_E) |
| { |
| #ifdef SIMULATOR |
| *lmacEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_CSMA_CA_BO_THR_E; |
| #else |
| *lmacEvent = MSK_F_FTDF_ON_OFF_REGMAP_CSMA_CA_BO_THR_E; |
| #endif |
| #if FTDF_USE_SLEEP_DURING_BACKOFF |
| |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.BOIrqCount++; |
| } |
| |
| FTDF_sdbFsmBackoffIRQ(); |
| #endif /* FTDF_USE_SLEEP_DURING_BACKOFF */ |
| } |
| |
| #endif |
| } |
| |
| static void sendConfirm(FTDF_Status status, |
| FTDF_MsgId msgId) |
| { |
| switch (msgId) |
| { |
| #ifndef FTDF_LITE |
| |
| case FTDF_DATA_REQUEST: |
| { |
| FTDF_DataRequest *dataRequest = (FTDF_DataRequest *) FTDF_reqCurrent; |
| |
| FTDF_Time timestamp = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_TXTIMESTAMP, |
| FTDF_TX_DATA_BUFFER); |
| FTDF_SN SN = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_MACSN, FTDF_TX_DATA_BUFFER); |
| FTDF_NumOfBackoffs numOfBackoffs = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_CSMACANRRETRIES, |
| FTDF_TX_DATA_BUFFER); |
| |
| FTDF_sendDataConfirm(dataRequest, status, |
| timestamp, |
| SN, |
| numOfBackoffs, |
| NULL); |
| |
| break; |
| } |
| |
| case FTDF_POLL_REQUEST: |
| |
| if (status != FTDF_SUCCESS) |
| { |
| FTDF_sendPollConfirm((FTDF_PollRequest *)FTDF_reqCurrent, status); |
| } |
| |
| break; |
| |
| case FTDF_ASSOCIATE_REQUEST: |
| |
| if (status != FTDF_SUCCESS) |
| { |
| FTDF_sendAssociateConfirm((FTDF_AssociateRequest *)FTDF_reqCurrent, |
| status, |
| 0xffff); |
| } |
| |
| break; |
| |
| case FTDF_ASSOCIATE_RESPONSE: |
| |
| if (status != FTDF_SUCCESS) |
| { |
| FTDF_AssociateResponse *assocResp = (FTDF_AssociateResponse *)FTDF_reqCurrent; |
| |
| FTDF_Address srcAddr, dstAddr; |
| srcAddr.extAddress = FTDF_pib.extAddress; |
| dstAddr.extAddress = assocResp->deviceAddress; |
| |
| FTDF_sendCommStatusIndication(FTDF_reqCurrent, status, |
| FTDF_pib.PANId, |
| FTDF_EXTENDED_ADDRESS, |
| srcAddr, |
| FTDF_EXTENDED_ADDRESS, |
| dstAddr, |
| assocResp->securityLevel, |
| assocResp->keyIdMode, |
| assocResp->keySource, |
| assocResp->keyIndex); |
| } |
| |
| break; |
| |
| case FTDF_ORPHAN_RESPONSE: |
| |
| if (status != FTDF_SUCCESS) |
| { |
| FTDF_OrphanResponse *orphanResp = (FTDF_OrphanResponse *)FTDF_reqCurrent; |
| |
| FTDF_Address srcAddr, dstAddr; |
| srcAddr.extAddress = FTDF_pib.extAddress; |
| dstAddr.extAddress = orphanResp->orphanAddress; |
| |
| FTDF_sendCommStatusIndication(FTDF_reqCurrent, status, |
| FTDF_pib.PANId, |
| FTDF_EXTENDED_ADDRESS, |
| srcAddr, |
| FTDF_EXTENDED_ADDRESS, |
| dstAddr, |
| orphanResp->securityLevel, |
| orphanResp->keyIdMode, |
| orphanResp->keySource, |
| orphanResp->keyIndex); |
| } |
| |
| break; |
| |
| case FTDF_DISASSOCIATE_REQUEST: |
| |
| if (status != FTDF_SUCCESS) |
| { |
| FTDF_sendDisassociateConfirm((FTDF_DisassociateRequest *)FTDF_reqCurrent, status); |
| } |
| |
| break; |
| |
| case FTDF_SCAN_REQUEST: |
| |
| if (status != FTDF_SUCCESS) |
| { |
| FTDF_sendScanConfirm((FTDF_ScanRequest *)FTDF_reqCurrent, status); |
| } |
| |
| break; |
| |
| case FTDF_BEACON_REQUEST: |
| FTDF_sendBeaconConfirm((FTDF_BeaconRequest *)FTDF_reqCurrent, status); |
| break; |
| |
| case FTDF_REMOTE_REQUEST: |
| FTDF_reqCurrent = NULL; |
| break; |
| #endif /* !FTDF_LITE */ |
| |
| case FTDF_TRANSPARENT_REQUEST: |
| { |
| #ifndef FTDF_PHY_API |
| FTDF_TransparentRequest *transparentRequest = (FTDF_TransparentRequest *) FTDF_reqCurrent; |
| #endif |
| FTDF_Bitmap32 transparentStatus = 0; |
| |
| switch (status) |
| { |
| case FTDF_SUCCESS: |
| transparentStatus = FTDF_TRANSPARENT_SEND_SUCCESSFUL; |
| break; |
| |
| case FTDF_CHANNEL_ACCESS_FAILURE: |
| transparentStatus = FTDF_TRANSPARENT_CSMACA_FAILURE; |
| break; |
| #if FTDF_TRANSPARENT_WAIT_FOR_ACK |
| |
| case FTDF_NO_ACK: |
| transparentStatus = FTDF_TRANSPARENT_NO_ACK; |
| break; |
| #endif |
| } |
| |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.TXSuccessCount++; |
| } |
| |
| #ifdef FTDF_PHY_API |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| FTDF_txInProgress = FTDF_FALSE; |
| FTDF_exitCritical(); |
| |
| FTDF_SEND_FRAME_TRANSPARENT_CONFIRM(NULL, transparentStatus); |
| #else |
| |
| FTDF_reqCurrent = NULL; |
| |
| FTDF_SEND_FRAME_TRANSPARENT_CONFIRM(transparentRequest->handle, |
| transparentStatus); |
| |
| FTDF_REL_MSG_BUFFER((FTDF_MsgBuffer *) transparentRequest); |
| #ifndef FTDF_LITE |
| FTDF_processNextRequest(); |
| #endif /* !FTDF_LITE */ |
| |
| #endif /* FTDF_PHY_API */ |
| break; |
| } |
| } |
| } |
| |
| void FTDF_processTxEvent(void) |
| { |
| volatile uint32_t *txFlagStatE; |
| FTDF_Status status = FTDF_SUCCESS; |
| |
| #if FTDF_USE_PTI && !FTDF_USE_AUTO_PTI |
| /* Restore Rx PTI in case the Tx transaction that just ended interrupted an Rx-always-on |
| * transaction. */ |
| hw_coex_pti_t tx_pti; |
| hw_coex_update_ftdf_pti(FTDF_getRxPti(), &tx_pti, true); |
| #endif |
| |
| txFlagStatE = FTDF_GET_FIELD_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_CLEAR_E, FTDF_TX_WAKEUP_BUFFER); |
| |
| if (*txFlagStatE & MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_E) |
| { |
| #ifdef SIMULATOR |
| *txFlagStatE &= ~MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_E; |
| #else |
| *txFlagStatE = MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_E; |
| #endif |
| |
| volatile uint32_t *txStatus = |
| FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_RETURN_STATUS_1, FTDF_TX_WAKEUP_BUFFER); |
| |
| if (*txStatus & MSK_F_FTDF_RETENTION_RAM_CSMACAFAIL) |
| { |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.TXFailCount++; |
| } |
| |
| status = FTDF_CHANNEL_ACCESS_FAILURE; |
| } |
| } |
| |
| txFlagStatE = FTDF_GET_FIELD_ADDR_INDEXED(ON_OFF_REGMAP_TX_FLAG_CLEAR_E, FTDF_TX_DATA_BUFFER); |
| |
| if (*txFlagStatE & MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_E) |
| { |
| #ifdef SIMULATOR |
| *txFlagStatE &= ~MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_E; |
| #else |
| *txFlagStatE = MSK_F_FTDF_ON_OFF_REGMAP_TX_FLAG_CLEAR_E; |
| #endif |
| } |
| else |
| { |
| return; |
| } |
| |
| #ifndef FTDF_PHY_API |
| FTDF_txInProgress = FTDF_FALSE; |
| |
| if (FTDF_reqCurrent == NULL) |
| { |
| return; |
| } |
| |
| #else |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| if (FTDF_txInProgress == FTDF_FALSE) |
| { |
| FTDF_exitCritical(); |
| return; |
| } |
| |
| FTDF_exitCritical(); |
| #endif |
| #if FTDF_USE_SLEEP_DURING_BACKOFF |
| FTDF_sdbFsmTxIRQ(); |
| #endif /* FTDF_USE_SLEEP_DURING_BACKOFF */ |
| FTDF_Boolean ackTX = FTDF_GET_FIELD_INDEXED(RETENTION_RAM_ACKREQUEST, FTDF_TX_DATA_BUFFER); |
| |
| if (status == FTDF_SUCCESS) |
| { |
| volatile uint32_t *txMeta = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_0, FTDF_TX_DATA_BUFFER); |
| FTDF_FrameType frameType = |
| (*txMeta & MSK_F_FTDF_RETENTION_RAM_FRAMETYPE) >> OFF_F_FTDF_RETENTION_RAM_FRAMETYPE; |
| |
| switch (frameType) |
| { |
| case FTDF_BEACON_FRAME: |
| FTDF_pib.trafficCounters.txBeaconFrmCnt++; |
| break; |
| |
| case FTDF_DATA_FRAME: |
| FTDF_pib.trafficCounters.txDataFrmCnt++; |
| break; |
| |
| case FTDF_MAC_COMMAND_FRAME: |
| FTDF_pib.trafficCounters.txCmdFrmCnt++; |
| break; |
| |
| case FTDF_MULTIPURPOSE_FRAME: |
| FTDF_pib.trafficCounters.txMultiPurpFrmCnt++; |
| break; |
| } |
| |
| volatile uint32_t *txStatus = |
| FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_RETURN_STATUS_1, FTDF_TX_DATA_BUFFER); |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_TSCH |
| FTDF_TschRetry *tschRetry = NULL; |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| tschRetry = FTDF_getTschRetry(FTDF_getRequestAddress(FTDF_reqCurrent)); |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| |
| if (*txStatus & MSK_F_FTDF_RETENTION_RAM_ACKFAIL) |
| { |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| tschRetry->nrOfRetries++; |
| FTDF_tschSlotLink->request = NULL; |
| status = FTDF_scheduleTsch(FTDF_reqCurrent); |
| |
| if (status == FTDF_SUCCESS) |
| { |
| // If FTDF_reqCurrent is not equal to NULL the retried request will be queued |
| // rather then send again |
| FTDF_reqCurrent = NULL; |
| } |
| } |
| else |
| #endif /* FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| |
| if (FTDF_nrOfRetries < FTDF_pib.maxFrameRetries) |
| { |
| FTDF_nrOfRetries++; |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_CSL |
| |
| if (FTDF_pib.leEnabled) |
| { |
| FTDF_setPeerCslTiming(NULL, 0); |
| |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| |
| FTDF_txInProgress = FTDF_TRUE; |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLSTARTSAMPLETIME, curTime + 5); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACWUPERIOD, FTDF_pib.CSLMaxPeriod); |
| |
| volatile uint32_t *txFlagSet = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_SET); |
| *txFlagSet |= ((1 << FTDF_TX_DATA_BUFFER) | (1 << FTDF_TX_WAKEUP_BUFFER)); |
| |
| FTDF_exitCritical(); |
| } |
| else |
| #endif /* FTDF_NO_CSL */ |
| #endif /* !FTDF_LITE */ |
| { |
| #if FTDF_USE_PTI && !FTDF_USE_AUTO_PTI |
| hw_coex_update_ftdf_pti(tx_pti, NULL, true); |
| #endif |
| volatile uint32_t *txFlagSet = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_SET); |
| *txFlagSet |= (1 << FTDF_TX_DATA_BUFFER); |
| } |
| |
| return; |
| } |
| else |
| { |
| if (FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.TXFailCount++; |
| } |
| |
| status = FTDF_NO_ACK; |
| } |
| } |
| else if (*txStatus & MSK_F_FTDF_RETENTION_RAM_CSMACAFAIL) |
| { |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| tschRetry->nrOfCcaRetries++; |
| |
| if (tschRetry->nrOfCcaRetries < FTDF_pib.maxCSMABackoffs) |
| { |
| FTDF_tschSlotLink->request = NULL; |
| status = FTDF_scheduleTsch(FTDF_reqCurrent); |
| |
| if (status == FTDF_SUCCESS) |
| { |
| // If FTDF_reqCurrent is not equal to NULL the retried request will be queued |
| // rather then send again |
| FTDF_reqCurrent = NULL; |
| } |
| } |
| else |
| { |
| status = FTDF_CHANNEL_ACCESS_FAILURE; |
| } |
| } |
| else |
| #endif /* FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| { |
| status = FTDF_CHANNEL_ACCESS_FAILURE; |
| } |
| |
| if (FTDF_pib.metricsEnabled && status != FTDF_SUCCESS) |
| { |
| FTDF_pib.performanceMetrics.TXFailCount++; |
| } |
| } |
| else |
| { |
| if (ackTX == FTDF_FALSE && FTDF_pib.metricsEnabled) |
| { |
| FTDF_pib.performanceMetrics.TXSuccessCount++; |
| } |
| |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| tschRetry->nrOfCcaRetries = 0; |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| } |
| } |
| |
| #ifndef FTDF_PHY_API |
| |
| if ((ackTX == FTDF_FALSE || status != FTDF_SUCCESS) && FTDF_reqCurrent) |
| { |
| sendConfirm(status, |
| FTDF_reqCurrent->msgId); |
| #ifndef FTDF_LITE |
| FTDF_processNextRequest(); |
| #endif /* !FTDF_LITE */ |
| } |
| |
| #else |
| |
| if (FTDF_txInProgress) |
| { |
| sendConfirm(status, FTDF_TRANSPARENT_REQUEST); |
| } |
| |
| #endif |
| } |
| |
| void FTDF_processSymbolTimerEvent(void) |
| { |
| volatile uint32_t *symbolTimeThrEvent = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_SYMBOLTIMETHR_E); |
| |
| #ifdef FTDF_PHY_API |
| volatile uint32_t *lmacReady4sleepEvent = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_LMACREADY4SLEEP_D); |
| |
| if (*lmacReady4sleepEvent & MSK_F_FTDF_ON_OFF_REGMAP_LMACREADY4SLEEP_D) |
| { |
| *lmacReady4sleepEvent = MSK_F_FTDF_ON_OFF_REGMAP_LMACREADY4SLEEP_D; |
| |
| /* If lmac ready 4 sleep, call respective callback, after disabling the interrupt */ |
| if (FTDF_GET_FIELD(ON_OFF_REGMAP_LMACREADY4SLEEP) == 1) |
| { |
| volatile uint32_t *lmacCtrlMask = FTDF_GET_REG_ADDR(ON_OFF_REGMAP_LMAC_CONTROL_MASK); |
| *lmacCtrlMask &= ~MSK_F_FTDF_ON_OFF_REGMAP_LMACREADY4SLEEP_M; |
| FTDF_LMACREADY4SLEEP_CB(FTDF_TRUE, 0); |
| } |
| } |
| |
| #endif |
| |
| // sync timestamp event |
| if (*symbolTimeThrEvent & MSK_F_FTDF_ON_OFF_REGMAP_SYNCTIMESTAMP_E) |
| { |
| #ifdef SIMULATOR |
| *symbolTimeThrEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_SYNCTIMESTAMP_E; |
| #else |
| *symbolTimeThrEvent = MSK_F_FTDF_ON_OFF_REGMAP_SYNCTIMESTAMP_E; |
| #endif |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYNCTIMESTAMPENA, 0); |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_CSL |
| FTDF_oldLeEnabled = FTDF_FALSE; |
| |
| if (FTDF_wakeUpEnableLe) |
| { |
| FTDF_pib.leEnabled = FTDF_TRUE; |
| FTDF_setLeEnabled(); |
| FTDF_wakeUpEnableLe = FTDF_FALSE; |
| } |
| |
| #endif /* FTDF_NO_CSL */ |
| |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_wakeUpEnableTsch) |
| { |
| FTDF_setTschEnabled(); |
| } |
| |
| #endif /* FTDF_NO_TSCH */ |
| |
| FTDF_restoreTxPendingTimer(); |
| #endif /* !FTDF_LITE */ |
| FTDF_WAKE_UP_READY(); |
| } |
| |
| // miscellaneous event |
| // - Non-TSCH mode: association timer |
| // - TSCH mode: next active link timer |
| if (*symbolTimeThrEvent & MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIME2THR_E) |
| { |
| #ifdef SIMULATOR |
| *symbolTimeThrEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIME2THR_E; |
| #else |
| *symbolTimeThrEvent = MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIME2THR_E; |
| #endif |
| |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| FTDF_tschProcessRequest(); |
| } |
| else |
| #endif /* FTDF_NO_TSCH */ |
| if (FTDF_reqCurrent && |
| FTDF_reqCurrent->msgId == FTDF_ASSOCIATE_REQUEST) |
| { |
| FTDF_AssocAdmin *assocAdmin = &FTDF_aa; |
| |
| // macResponseWaitTime expired |
| assocAdmin->dataR = FTDF_TRUE; |
| |
| FTDF_sendAssociateDataRequest(); |
| } |
| |
| #endif /* !FTDF_LITE */ |
| } |
| |
| // pending queue symbol timer event |
| if (*symbolTimeThrEvent & MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIMETHR_E) |
| { |
| #ifdef SIMULATOR |
| *symbolTimeThrEvent &= ~MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIMETHR_E; |
| #else |
| *symbolTimeThrEvent = MSK_F_FTDF_ON_OFF_REGMAP_SYMBOLTIMETHR_E; |
| #endif |
| |
| #ifndef FTDF_LITE |
| FTDF_removeTxPendingTimer(NULL); |
| #endif /* !FTDF_LITE */ |
| } |
| } |
| |
| #ifndef FTDF_LITE |
| FTDF_Status FTDF_sendFrame(FTDF_ChannelNumber channel, |
| FTDF_FrameHeader *frameHeader, |
| FTDF_SecurityHeader *securityHeader, |
| FTDF_Octet *txPtr, |
| FTDF_DataLength payloadSize, |
| FTDF_Octet *payload) |
| { |
| FTDF_Octet *txBufPtr = (FTDF_Octet *) FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO); |
| |
| FTDF_DataLength micLength = FTDF_getMicLength(securityHeader->securityLevel); |
| FTDF_DataLength phyPayloadSize = (txPtr - txBufPtr) - 1 + payloadSize + micLength + FTDF_FCS_LENGTH; |
| |
| if (phyPayloadSize > (FTDF_BUFFER_LENGTH - 1)) |
| { |
| return FTDF_FRAME_TOO_LONG; |
| } |
| |
| *txBufPtr = phyPayloadSize; |
| |
| FTDF_Octet *privPtr = txPtr; |
| |
| int n; |
| |
| for (n = 0; n < payloadSize; n++) |
| { |
| *txPtr++ = *payload++; |
| } |
| |
| FTDF_Status status = FTDF_secureFrame(txBufPtr, |
| privPtr, |
| frameHeader, |
| securityHeader); |
| |
| if (status != FTDF_SUCCESS) |
| { |
| return status; |
| } |
| |
| FTDF_Bitmap8 options = frameHeader->options; |
| |
| volatile uint32_t *metaData0 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_0, FTDF_TX_DATA_BUFFER); |
| volatile uint32_t *metaData1 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_1, FTDF_TX_DATA_BUFFER); |
| |
| uint16_t phyAttr = (FTDF_pib.CCAMode & 0x3) | 0x08 | ((channel - 11) & 0x0F) << 4 | |
| (FTDF_pib.TXPower & 0x07) << 12; |
| |
| metaData0 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_0, FTDF_TX_DATA_BUFFER); |
| metaData1 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_1, FTDF_TX_DATA_BUFFER); |
| |
| *metaData0 = |
| ((phyPayloadSize << OFF_F_FTDF_RETENTION_RAM_FRAME_LENGTH) & MSK_F_FTDF_RETENTION_RAM_FRAME_LENGTH) | |
| ((phyAttr << OFF_F_FTDF_RETENTION_RAM_PHYATTR) & MSK_F_FTDF_RETENTION_RAM_PHYATTR) | |
| ((frameHeader->frameType << OFF_F_FTDF_RETENTION_RAM_FRAMETYPE) & MSK_F_FTDF_RETENTION_RAM_FRAMETYPE) | |
| MSK_F_FTDF_RETENTION_RAM_CSMACA_ENA | |
| ((options & FTDF_OPT_ACK_REQUESTED) ? MSK_F_FTDF_RETENTION_RAM_ACKREQUEST : 0) | |
| MSK_F_FTDF_RETENTION_RAM_CRC16_ENA; |
| |
| *metaData1 = |
| ((frameHeader->SN << OFF_F_FTDF_RETENTION_RAM_MACSN) & MSK_F_FTDF_RETENTION_RAM_MACSN); |
| |
| uint32_t phyCsmaCaAttr = (FTDF_pib.CCAMode & 0x3) | ((channel - 11) & 0xf) << 4 | |
| (FTDF_pib.TXPower & 0x07) << 12; |
| FTDF_SET_FIELD(ON_OFF_REGMAP_PHYCSMACAATTR, phyCsmaCaAttr); |
| |
| #ifndef FTDF_NO_CSL |
| |
| if (FTDF_pib.leEnabled == FTDF_TRUE) |
| { |
| if (frameHeader->dstAddrMode != FTDF_SHORT_ADDRESS) |
| { |
| return FTDF_NO_SHORT_ADDRESS; |
| } |
| |
| // Clear CSMACA of data frame buffer |
| *metaData0 &= ~MSK_F_FTDF_RETENTION_RAM_CSMACA_ENA; |
| |
| txPtr = txBufPtr = ((FTDF_Octet *) FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO)) + |
| (FTDF_BUFFER_LENGTH * FTDF_TX_WAKEUP_BUFFER); |
| |
| *txPtr++ = 0x0d; |
| *txPtr++ = 0x2d; |
| *txPtr++ = 0x81; |
| *txPtr++ = frameHeader->SN; |
| *(FTDF_PANId *) txPtr = frameHeader->dstPANId; |
| txPtr += 2; |
| *(FTDF_ShortAddress *) txPtr = frameHeader->dstAddr.shortAddress; |
| txPtr += 2; |
| *txPtr++ = 0x82; |
| *txPtr++ = 0x0e; |
| |
| metaData0 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_0, FTDF_TX_WAKEUP_BUFFER); |
| metaData1 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_1, FTDF_TX_WAKEUP_BUFFER); |
| volatile uint32_t *txPriority = |
| FTDF_GET_REG_ADDR_INDEXED(ON_OFF_REGMAP_TX_PRIORITY, FTDF_TX_WAKEUP_BUFFER); |
| |
| *metaData0 = |
| ((0x0d << OFF_F_FTDF_RETENTION_RAM_FRAME_LENGTH) & MSK_F_FTDF_RETENTION_RAM_FRAME_LENGTH) | |
| ((phyAttr << OFF_F_FTDF_RETENTION_RAM_PHYATTR) & MSK_F_FTDF_RETENTION_RAM_PHYATTR) | |
| ((FTDF_MULTIPURPOSE_FRAME << OFF_F_FTDF_RETENTION_RAM_FRAMETYPE) & MSK_F_FTDF_RETENTION_RAM_FRAMETYPE) | |
| MSK_F_FTDF_RETENTION_RAM_CSMACA_ENA | |
| MSK_F_FTDF_RETENTION_RAM_CRC16_ENA; |
| |
| *metaData1 = |
| ((frameHeader->SN << OFF_F_FTDF_RETENTION_RAM_MACSN) & MSK_F_FTDF_RETENTION_RAM_MACSN); |
| #if FTDF_USE_PTI && FTDF_USE_AUTO_PTI |
| *txPriority |= MSK_F_FTDF_ON_OFF_REGMAP_ISWAKEUP; |
| #else |
| *txPriority = MSK_F_FTDF_ON_OFF_REGMAP_ISWAKEUP; |
| #endif |
| } |
| |
| #endif /* FTDF_NO_CSL */ |
| |
| volatile uint32_t *txFlagSet = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_SET); |
| |
| #ifndef FTDF_NO_CSL |
| |
| if (FTDF_pib.leEnabled == FTDF_TRUE) |
| { |
| FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| FTDF_Time delta = curTime - FTDF_rzTime; |
| |
| if (delta > 0x80000000) |
| { |
| // Receiving an wakeup frame sequence, delay sending until RZ has passed. |
| FTDF_sendFramePending = frameHeader->dstAddr.shortAddress; |
| } |
| else |
| { |
| FTDF_Time wakeupStartTime; |
| FTDF_Period wakeupPeriod; |
| |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| FTDF_getWakeupParams(frameHeader->dstAddr.shortAddress, &wakeupStartTime, &wakeupPeriod); |
| |
| FTDF_txInProgress = FTDF_TRUE; |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLSTARTSAMPLETIME, wakeupStartTime); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACWUPERIOD, wakeupPeriod); |
| |
| *txFlagSet |= ((1 << FTDF_TX_DATA_BUFFER) | (1 << FTDF_TX_WAKEUP_BUFFER)); |
| |
| FTDF_exitCritical(); |
| } |
| } |
| else |
| #endif /* FTDF_NO_CSL */ |
| if (!FTDF_pib.tschEnabled) |
| { |
| *txFlagSet |= (1 << FTDF_TX_DATA_BUFFER); |
| // SetWord16(P2_SET_DATA_REG, (1 << 3)); |
| // SetWord16(P23_MODE_REG, 0x300); // SW trigger - output |
| // for (volatile int k = 0; k < 100; k++) { |
| // } |
| // SetWord16(P23_MODE_REG, 0x000);// SW trigger - high Z |
| |
| |
| } |
| |
| return FTDF_SUCCESS; |
| } |
| |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| FTDF_Status FTDF_sendAckFrame(FTDF_FrameHeader *frameHeader, |
| FTDF_SecurityHeader *securityHeader, |
| FTDF_Octet *txPtr) |
| { |
| FTDF_Octet *txBufPtr = ((FTDF_Octet *) FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO)) + |
| 2 * FTDF_BUFFER_LENGTH; |
| FTDF_DataLength micLength = FTDF_getMicLength(securityHeader->securityLevel); |
| FTDF_DataLength phyPayloadSize = (txPtr - txBufPtr) - 1 + micLength + FTDF_FCS_LENGTH; |
| |
| *txBufPtr = phyPayloadSize; |
| |
| FTDF_Status status = FTDF_secureFrame(txBufPtr, |
| txPtr, |
| frameHeader, |
| securityHeader); |
| |
| if (status != FTDF_SUCCESS) |
| { |
| return status; |
| } |
| |
| volatile uint32_t *metaData0 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_0, FTDF_TX_ACK_BUFFER); |
| volatile uint32_t *metaData1 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_1, FTDF_TX_ACK_BUFFER); |
| volatile uint32_t *txPriority = FTDF_GET_REG_ADDR_INDEXED(ON_OFF_REGMAP_TX_PRIORITY, FTDF_TX_ACK_BUFFER); |
| |
| uint16_t phyAttr = |
| (FTDF_pib.CCAMode & 0x3) | 0x08 | (FTDF_GET_FIELD(ON_OFF_REGMAP_PHYRXATTR) & 0x00f0) | |
| (FTDF_pib.TXPower & 0x07) << 12; |
| |
| *metaData0 = |
| ((phyPayloadSize << OFF_F_FTDF_RETENTION_RAM_FRAME_LENGTH) & MSK_F_FTDF_RETENTION_RAM_FRAME_LENGTH) | |
| ((phyAttr << OFF_F_FTDF_RETENTION_RAM_PHYATTR) & MSK_F_FTDF_RETENTION_RAM_PHYATTR) | |
| ((FTDF_ACKNOWLEDGEMENT_FRAME << OFF_F_FTDF_RETENTION_RAM_FRAMETYPE) & MSK_F_FTDF_RETENTION_RAM_FRAMETYPE) | |
| MSK_F_FTDF_RETENTION_RAM_CRC16_ENA; |
| |
| *metaData1 = |
| ((frameHeader->SN << OFF_F_FTDF_RETENTION_RAM_MACSN) & MSK_F_FTDF_RETENTION_RAM_MACSN); |
| |
| #if FTDF_USE_PTI && FTDF_USE_AUTO_PTI |
| *txPriority |= 1; |
| #else |
| *txPriority = 1; |
| #endif |
| |
| volatile uint32_t *txFlagSet = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_SET); |
| |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| FTDF_Period txAckDelayVal = FTDF_GET_FIELD(ON_OFF_REGMAP_MACTSTXACKDELAYVAL); |
| |
| if (txAckDelayVal > 20) |
| { |
| *txFlagSet |= 1 << FTDF_TX_ACK_BUFFER; |
| } |
| |
| FTDF_exitCritical(); |
| } |
| else |
| #endif /* FTDF_NO_TSCH */ |
| { |
| *txFlagSet |= 1 << FTDF_TX_ACK_BUFFER; |
| } |
| |
| FTDF_pib.trafficCounters.txEnhAckFrmCnt++; |
| |
| return FTDF_SUCCESS; |
| } |
| #endif /* !FTDF_NO_CSL || !FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| |
| void FTDF_sendTransparentFrame(FTDF_DataLength frameLength, |
| FTDF_Octet *frame, |
| FTDF_ChannelNumber channel, |
| FTDF_PTI pti, |
| FTDF_Boolean cmsaSuppress) |
| { |
| volatile uint32_t *metaData0 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_0, FTDF_TX_DATA_BUFFER); |
| volatile uint32_t *metaData1 = FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_1, FTDF_TX_DATA_BUFFER); |
| volatile uint32_t *txPriority = FTDF_GET_REG_ADDR_INDEXED(ON_OFF_REGMAP_TX_PRIORITY, FTDF_TX_DATA_BUFFER); |
| |
| #if FTDF_TRANSPARENT_USE_WAIT_FOR_ACK |
| FTDF_Boolean useAck = FTDF_FALSE; |
| //FTDF_FrameHeader* frameHeader = &FTDF_fh; |
| FTDF_FrameHeader frameHeader; |
| FTDF_SN SN; |
| #endif |
| uint16_t phyAttr = (FTDF_pib.CCAMode & 0x3) | 0x08 | ((channel - 11) & 0x0F) << 4 | |
| (FTDF_pib.TXPower & 0x07) << 12; |
| #if FTDF_TRANSPARENT_USE_WAIT_FOR_ACK |
| |
| if (FTDF_transparentModeOptions & FTDF_TRANSPARENT_WAIT_FOR_ACK) |
| { |
| FTDF_getFrameHeader(frame, &frameHeader); |
| |
| if (frameHeader.options & FTDF_OPT_ACK_REQUESTED) |
| { |
| useAck = FTDF_TRUE; |
| } |
| |
| SN = frameHeader.SN; |
| } |
| |
| #endif |
| |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| *txPriority = ((pti << OFF_F_FTDF_ON_OFF_REGMAP_PTI_TX) & |
| MSK_F_FTDF_ON_OFF_REGMAP_PTI_TX) | 1; |
| #endif |
| *metaData0 = |
| ((frameLength << OFF_F_FTDF_RETENTION_RAM_FRAME_LENGTH) & MSK_F_FTDF_RETENTION_RAM_FRAME_LENGTH) | |
| ((phyAttr << OFF_F_FTDF_RETENTION_RAM_PHYATTR) & MSK_F_FTDF_RETENTION_RAM_PHYATTR) | |
| (((*frame & 0x7) << OFF_F_FTDF_RETENTION_RAM_FRAMETYPE) & MSK_F_FTDF_RETENTION_RAM_FRAMETYPE) | |
| ((cmsaSuppress) ? 0 : MSK_F_FTDF_RETENTION_RAM_CSMACA_ENA) | |
| #if FTDF_TRANSPARENT_USE_WAIT_FOR_ACK |
| ((useAck) ? MSK_F_FTDF_RETENTION_RAM_ACKREQUEST : 0) | |
| #endif |
| ((FTDF_transparentModeOptions & |
| FTDF_TRANSPARENT_ENABLE_FCS_GENERATION) ? MSK_F_FTDF_RETENTION_RAM_CRC16_ENA : 0); |
| |
| #if FTDF_TRANSPARENT_USE_WAIT_FOR_ACK |
| |
| if (useAck) |
| { |
| *metaData1 = ((SN << OFF_F_FTDF_RETENTION_RAM_MACSN) & MSK_F_FTDF_RETENTION_RAM_MACSN); |
| } |
| else |
| { |
| *metaData1 = ((0 << OFF_F_FTDF_RETENTION_RAM_MACSN) & MSK_F_FTDF_RETENTION_RAM_MACSN); |
| } |
| |
| #else |
| *metaData1 = |
| ((0 << OFF_F_FTDF_RETENTION_RAM_MACSN) & MSK_F_FTDF_RETENTION_RAM_MACSN); |
| #endif |
| |
| uint32_t phyCsmaCaAttr = (FTDF_pib.CCAMode & 0x3) | ((channel - 11) & 0xf) << 4 | |
| (FTDF_pib.TXPower & 0x07) << 12; |
| FTDF_SET_FIELD(ON_OFF_REGMAP_PHYCSMACAATTR, phyCsmaCaAttr); |
| #if FTDF_USE_PTI && !FTDF_USE_AUTO_PTI |
| hw_coex_update_ftdf_pti((hw_coex_pti_t) pti, NULL, true); |
| #else |
| // FTDF_SET_FIELD(ON_OFF_REGMAP_PTI_TX, pti); |
| #endif |
| volatile uint32_t *txFlagSet = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_SET); |
| *txFlagSet |= (1 << FTDF_TX_DATA_BUFFER); |
| } |
| |
| void FTDF_initQueues(void) |
| { |
| #ifndef FTDF_LITE |
| FTDF_initQueue(&FTDF_freeQueue); |
| FTDF_initQueue(&FTDF_reqQueue); |
| |
| int n; |
| |
| for (n = 0; n < FTDF_NR_OF_REQ_BUFFERS; n++) |
| { |
| FTDF_queueBufferHead(&FTDF_reqBuffers[ n ], &FTDF_freeQueue); |
| |
| FTDF_txPendingList[ n ].addr.extAddress = 0xFFFFFFFFFFFFFFFFLL; |
| FTDF_txPendingList[ n ].addrMode = FTDF_NO_ADDRESS; |
| FTDF_txPendingList[ n ].PANId = 0xFFFF; |
| FTDF_initQueue(&FTDF_txPendingList[ n ].queue); |
| |
| FTDF_txPendingTimerList[ n ].free = FTDF_TRUE; |
| FTDF_txPendingTimerList[ n ].next = NULL; |
| } |
| |
| FTDF_txPendingTimerHead = FTDF_txPendingTimerList; |
| FTDF_txPendingTimerTime = 0; |
| #endif /* !FTDF_LITE */ |
| #ifndef FTDF_PHY_API |
| FTDF_reqCurrent = NULL; |
| #endif |
| } |
| |
| #ifndef FTDF_LITE |
| void FTDF_initQueue(FTDF_Queue *queue) |
| { |
| queue->head.next = (FTDF_Buffer *) &queue->tail; |
| queue->head.prev = NULL; |
| queue->tail.next = NULL; |
| queue->tail.prev = (FTDF_Buffer *) &queue->head; |
| } |
| |
| void FTDF_queueBufferHead(FTDF_Buffer *buffer, FTDF_Queue *queue) |
| { |
| FTDF_Buffer *next = queue->head.next; |
| |
| queue->head.next = buffer; |
| next->header.prev = buffer; |
| buffer->header.next = next; |
| buffer->header.prev = (FTDF_Buffer *) &queue->head; |
| } |
| |
| FTDF_Buffer *FTDF_dequeueBufferTail(FTDF_Queue *queue) |
| { |
| FTDF_Buffer *buffer = queue->tail.prev; |
| |
| if (buffer->header.prev == NULL) |
| { |
| return NULL; |
| } |
| |
| queue->tail.prev = buffer->header.prev; |
| buffer->header.prev->header.next = (FTDF_Buffer *) &queue->tail; |
| |
| return buffer; |
| } |
| |
| FTDF_Status FTDF_queueReqHead(FTDF_MsgBuffer *request, FTDF_Queue *queue) |
| { |
| FTDF_Buffer *buffer = FTDF_dequeueBufferTail(&FTDF_freeQueue); |
| |
| if (buffer == NULL) |
| { |
| return FTDF_TRANSACTION_OVERFLOW; |
| } |
| |
| FTDF_Buffer *next = queue->head.next; |
| |
| queue->head.next = buffer; |
| next->header.prev = buffer; |
| buffer->header.next = next; |
| buffer->header.prev = (FTDF_Buffer *) &queue->head; |
| buffer->request = request; |
| |
| return FTDF_SUCCESS; |
| } |
| |
| FTDF_MsgBuffer *FTDF_dequeueReqTail(FTDF_Queue *queue) |
| { |
| FTDF_Buffer *buffer = queue->tail.prev; |
| |
| if (buffer->header.prev == NULL) |
| { |
| return NULL; |
| } |
| |
| queue->tail.prev = buffer->header.prev; |
| buffer->header.prev->header.next = (FTDF_Buffer *) &queue->tail; |
| |
| FTDF_MsgBuffer *request = buffer->request; |
| |
| FTDF_queueBufferHead(buffer, &FTDF_freeQueue); |
| |
| return request; |
| } |
| |
| FTDF_MsgBuffer *FTDF_dequeueByHandle(FTDF_Handle handle, FTDF_Queue *queue) |
| { |
| FTDF_Buffer *buffer = queue->head.next; |
| |
| while (buffer->header.next != NULL) |
| { |
| if (buffer->request && |
| buffer->request->msgId == FTDF_DATA_REQUEST && |
| ((FTDF_DataRequest *) buffer->request)->msduHandle == handle) |
| { |
| buffer->header.prev->header.next = buffer->header.next; |
| buffer->header.next->header.prev = buffer->header.prev; |
| |
| FTDF_MsgBuffer *request = buffer->request; |
| |
| FTDF_queueBufferHead(buffer, &FTDF_freeQueue); |
| |
| return request; |
| } |
| |
| buffer = buffer->header.next; |
| } |
| |
| return NULL; |
| } |
| |
| FTDF_MsgBuffer *FTDF_dequeueByRequest(FTDF_MsgBuffer *request, FTDF_Queue *queue) |
| { |
| FTDF_Buffer *buffer = queue->head.next; |
| |
| while (buffer->header.next != NULL) |
| { |
| if (buffer->request == request) |
| { |
| buffer->header.prev->header.next = buffer->header.next; |
| buffer->header.next->header.prev = buffer->header.prev; |
| |
| FTDF_MsgBuffer *req = buffer->request; |
| |
| FTDF_queueBufferHead(buffer, &FTDF_freeQueue); |
| |
| return req; |
| } |
| |
| buffer = buffer->header.next; |
| } |
| |
| return NULL; |
| } |
| |
| FTDF_Boolean FTDF_isQueueEmpty(FTDF_Queue *queue) |
| { |
| if (queue->head.next->header.next == NULL) |
| { |
| return FTDF_TRUE; |
| } |
| else |
| { |
| return FTDF_FALSE; |
| } |
| } |
| |
| static FTDF_PendingTL *FTDF_findFreePendingTimer(void) |
| { |
| uint8_t i; |
| |
| for (i = 0; i < FTDF_NR_OF_REQ_BUFFERS; i++) |
| { |
| if (FTDF_txPendingTimerList[ i ].free == FTDF_TRUE) |
| { |
| break; |
| } |
| } |
| |
| return &FTDF_txPendingTimerList[ i ]; |
| } |
| |
| void FTDF_addTxPendingTimer(FTDF_MsgBuffer *request, uint8_t pendListNr, FTDF_Time delta, void (* func)( |
| FTDF_PendingTL *)) |
| { |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| FTDF_PendingTL *ptr = FTDF_txPendingTimerHead; |
| FTDF_Time timestamp = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| |
| if (ptr->free == FTDF_FALSE) |
| { |
| while (ptr) |
| { |
| ptr->delta -= timestamp - FTDF_txPendingTimerLT; |
| ptr = ptr->next; |
| } |
| } |
| |
| FTDF_txPendingTimerLT = timestamp; |
| ptr = FTDF_txPendingTimerHead; |
| |
| if (ptr->free == FTDF_TRUE) |
| { |
| ptr->free = FTDF_FALSE; |
| ptr->next = NULL; |
| ptr->request = request; |
| ptr->delta = delta; |
| ptr->pendListNr = pendListNr; |
| ptr->func = func; |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYMBOLTIMETHR, delta + timestamp); |
| FTDF_txPendingTimerTime = delta + timestamp; |
| FTDF_exitCritical(); |
| return; |
| } |
| |
| if (ptr->delta > delta) |
| { |
| FTDF_txPendingTimerHead = FTDF_findFreePendingTimer(); |
| FTDF_txPendingTimerHead->free = FTDF_FALSE; |
| FTDF_txPendingTimerHead->next = ptr; |
| FTDF_txPendingTimerHead->request = request; |
| FTDF_txPendingTimerHead->delta = delta; |
| FTDF_txPendingTimerHead->pendListNr = pendListNr; |
| FTDF_txPendingTimerHead->func = func; |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYMBOLTIMETHR, delta + timestamp); |
| FTDF_txPendingTimerTime = delta + timestamp; |
| FTDF_exitCritical(); |
| return; |
| } |
| else if (ptr->delta == delta) |
| { |
| delta++; |
| } |
| |
| FTDF_PendingTL *prev; |
| |
| while (ptr->next) |
| { |
| prev = ptr; |
| ptr = ptr->next; |
| |
| if (ptr->delta == delta) |
| { |
| delta++; |
| } |
| |
| if (prev->delta < delta && ptr->delta > delta) |
| { |
| prev->next = FTDF_findFreePendingTimer(); |
| prev->next->next = ptr; |
| ptr = prev->next; |
| ptr->free = FTDF_FALSE; |
| ptr->request = request; |
| ptr->delta = delta; |
| ptr->pendListNr = pendListNr; |
| ptr->func = func; |
| |
| FTDF_exitCritical(); |
| return; |
| } |
| } |
| |
| ptr->next = FTDF_findFreePendingTimer(); |
| ptr = ptr->next; |
| ptr->free = FTDF_FALSE; |
| ptr->next = NULL; |
| ptr->request = request; |
| ptr->delta = delta; |
| ptr->pendListNr = pendListNr; |
| ptr->func = func; |
| |
| FTDF_exitCritical(); |
| } |
| |
| void FTDF_removeTxPendingTimer(FTDF_MsgBuffer *request) |
| { |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| FTDF_PendingTL *ptr = FTDF_txPendingTimerHead; |
| FTDF_Time timestamp = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| |
| if (ptr->free == FTDF_TRUE) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYMBOLTIMETHR, timestamp - 1); |
| FTDF_txPendingTimerTime = timestamp - 1; |
| FTDF_exitCritical(); |
| return; |
| } |
| |
| while (ptr) |
| { |
| ptr->delta -= timestamp - FTDF_txPendingTimerLT; |
| ptr = ptr->next; |
| } |
| |
| FTDF_txPendingTimerLT = timestamp; |
| ptr = FTDF_txPendingTimerHead; |
| |
| if (!request || ptr->request == request) |
| { |
| if (ptr->next) |
| { |
| FTDF_PendingTL *temp = ptr; |
| |
| if (ptr->next->delta < 75) |
| { |
| while (temp) |
| { |
| temp->delta += 75; |
| temp = temp->next; |
| } |
| } |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYMBOLTIMETHR, timestamp + ptr->next->delta); |
| FTDF_txPendingTimerTime = timestamp + ptr->next->delta; |
| FTDF_txPendingTimerHead = ptr->next; |
| |
| ptr->free = FTDF_TRUE; |
| ptr->next = NULL; |
| } |
| else |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYMBOLTIMETHR, timestamp - 1); |
| FTDF_txPendingTimerTime = timestamp - 1; |
| |
| ptr->free = FTDF_TRUE; |
| ptr->next = NULL; |
| } |
| |
| FTDF_exitCritical(); |
| |
| if (!request) |
| { |
| if (ptr->func) |
| { |
| ptr->func(ptr); |
| } |
| } |
| |
| return; |
| } |
| |
| FTDF_PendingTL *prev = ptr; |
| |
| while (ptr->next) |
| { |
| prev = ptr; |
| ptr = ptr->next; |
| |
| if (ptr->request == request) |
| { |
| prev->next = ptr->next; |
| ptr->free = FTDF_TRUE; |
| ptr->next = NULL; |
| |
| FTDF_exitCritical(); |
| return; |
| } |
| } |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYMBOLTIMETHR, timestamp - 1); |
| FTDF_txPendingTimerTime = timestamp - 1; |
| FTDF_exitCritical(); |
| } |
| |
| void FTDF_restoreTxPendingTimer(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_SYMBOLTIMETHR, FTDF_txPendingTimerTime); |
| } |
| |
| FTDF_Boolean FTDF_getTxPendingTimerHead(FTDF_Time *time) |
| { |
| FTDF_PendingTL *ptr = FTDF_txPendingTimerHead; |
| |
| if (ptr->free == FTDF_TRUE) |
| { |
| return FTDF_FALSE; |
| } |
| |
| *time = FTDF_txPendingTimerTime; |
| return FTDF_TRUE; |
| } |
| |
| #ifndef FTDF_NO_TSCH |
| void FTDF_processKeepAliveTimerExp(FTDF_PendingTL *ptr) |
| { |
| FTDF_RemoteRequest *remoteRequest = (FTDF_RemoteRequest *)ptr->request; |
| |
| remoteRequest->msgId = FTDF_REMOTE_REQUEST; |
| remoteRequest->remoteId = FTDF_REMOTE_KEEP_ALIVE; |
| remoteRequest->dstAddr = FTDF_neighborTable[ ptr->pendListNr ].dstAddr; |
| |
| FTDF_processRemoteRequest(remoteRequest); |
| } |
| #endif /* FTDF_NO_TSCH */ |
| |
| void FTDF_sendTransactionExpired(FTDF_PendingTL *ptr) |
| { |
| FTDF_MsgBuffer *req = |
| FTDF_dequeueByRequest(ptr->request, &FTDF_txPendingList[ ptr->pendListNr ].queue); |
| |
| if (!req) |
| { |
| return; |
| } |
| |
| if (FTDF_isQueueEmpty(&FTDF_txPendingList[ ptr->pendListNr ].queue)) |
| { |
| #ifndef FTDF_NO_TSCH |
| |
| if (FTDF_pib.tschEnabled) |
| { |
| FTDF_txPendingList[ ptr->pendListNr ].addr.shortAddress = 0xfffe; |
| } |
| else |
| #endif /* FTDF_NO_TSCH */ |
| { |
| #if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO |
| |
| if (FTDF_txPendingList[ ptr->pendListNr ].addrMode == FTDF_SHORT_ADDRESS) |
| { |
| uint8_t entry, shortAddrIdx; |
| FTDF_Boolean found = FTDF_fpprLookupShortAddress( |
| FTDF_txPendingList[ ptr->pendListNr ].addr.shortAddress, &entry, |
| &shortAddrIdx); |
| ASSERT_WARNING(found); |
| FTDF_fpprSetShortAddressValid(entry, shortAddrIdx, FTDF_FALSE); |
| } |
| else if (FTDF_txPendingList[ ptr->pendListNr ].addrMode == FTDF_EXTENDED_ADDRESS) |
| { |
| uint8_t entry; |
| FTDF_Boolean found = FTDF_fpprLookupExtAddress( |
| FTDF_txPendingList[ ptr->pendListNr ].addr.extAddress, &entry); |
| ASSERT_WARNING(found); |
| FTDF_fpprSetExtAddressValid(entry, FTDF_FALSE); |
| } |
| else |
| { |
| ASSERT_WARNING(0); |
| } |
| |
| #endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */ |
| FTDF_txPendingList[ ptr->pendListNr ].addrMode = FTDF_NO_ADDRESS; |
| } |
| } |
| |
| switch (req->msgId) |
| { |
| case FTDF_DATA_REQUEST: |
| { |
| FTDF_DataRequest *dataRequest = (FTDF_DataRequest *)req; |
| |
| FTDF_sendDataConfirm(dataRequest, FTDF_TRANSACTION_EXPIRED, 0, 0, 0, NULL); |
| |
| break; |
| } |
| |
| case FTDF_ASSOCIATE_REQUEST: |
| { |
| FTDF_AssociateRequest *associateRequest = (FTDF_AssociateRequest *)req; |
| |
| FTDF_sendAssociateConfirm(associateRequest, FTDF_TRANSACTION_EXPIRED, 0xffff); |
| |
| break; |
| } |
| |
| case FTDF_ASSOCIATE_RESPONSE: |
| { |
| FTDF_AssociateResponse *assocResp = (FTDF_AssociateResponse *)req; |
| |
| FTDF_Address srcAddr, dstAddr; |
| srcAddr.extAddress = FTDF_pib.extAddress; |
| dstAddr.extAddress = assocResp->deviceAddress; |
| |
| FTDF_sendCommStatusIndication(req, FTDF_TRANSACTION_EXPIRED, |
| FTDF_pib.PANId, |
| FTDF_EXTENDED_ADDRESS, |
| srcAddr, |
| FTDF_EXTENDED_ADDRESS, |
| dstAddr, |
| assocResp->securityLevel, |
| assocResp->keyIdMode, |
| assocResp->keySource, |
| assocResp->keyIndex); |
| |
| break; |
| } |
| |
| case FTDF_DISASSOCIATE_REQUEST: |
| { |
| FTDF_DisassociateRequest *disReq = (FTDF_DisassociateRequest *)req; |
| |
| FTDF_sendDisassociateConfirm(disReq, FTDF_TRANSACTION_EXPIRED); |
| |
| break; |
| } |
| |
| case FTDF_BEACON_REQUEST: |
| { |
| FTDF_BeaconRequest *beaconRequest = (FTDF_BeaconRequest *)req; |
| |
| FTDF_sendBeaconConfirm(beaconRequest, FTDF_TRANSACTION_EXPIRED); |
| |
| break; |
| } |
| } |
| } |
| |
| #ifndef FTDF_NO_TSCH |
| void FTDF_resetKeepAliveTimer(FTDF_ShortAddress dstAddr) |
| { |
| uint8_t n; |
| |
| for (n = 0; n < FTDF_NR_OF_NEIGHBORS; n++) |
| { |
| if (FTDF_neighborTable[ n ].dstAddr == dstAddr) |
| { |
| break; |
| } |
| } |
| |
| if (n == FTDF_NR_OF_NEIGHBORS) |
| { |
| return; |
| } |
| |
| FTDF_removeTxPendingTimer((FTDF_MsgBuffer *)&FTDF_neighborTable[ n ].msg); |
| |
| FTDF_Time tsTimeslotLength = (FTDF_Time) FTDF_pib.timeslotTemplate.tsTimeslotLength / 16; |
| FTDF_Time delta = tsTimeslotLength * FTDF_neighborTable[ n ].period; |
| |
| FTDF_addTxPendingTimer((FTDF_MsgBuffer *)&FTDF_neighborTable[ n ].msg, n, delta, FTDF_processKeepAliveTimerExp); |
| } |
| #endif /* FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| |
| void FTDF_enableTransparentMode(FTDF_Boolean enable, |
| FTDF_Bitmap32 options) |
| { |
| #ifndef FTDF_LITE |
| |
| if (FTDF_pib.leEnabled == FTDF_TRUE || |
| FTDF_pib.tschEnabled == FTDF_TRUE) |
| { |
| return; |
| } |
| |
| #endif /* !FTDF_LITE */ |
| |
| FTDF_transparentMode = enable; |
| FTDF_transparentModeOptions = options; |
| |
| if (enable) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSFRMTYPE, |
| (options & FTDF_TRANSPARENT_PASS_ALL_FRAME_TYPES)); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_DISRXACKREQUESTCA, (options & FTDF_TRANSPARENT_AUTO_ACK ? 0 : 1)); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSCRCERROR, (options & FTDF_TRANSPARENT_PASS_CRC_ERROR ? 1 : 0)); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSRESFRAMEVERSION, |
| (options & FTDF_TRANSPARENT_PASS_ALL_FRAME_VERSION ? 1 : 0)); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSWRONGDPANID, |
| (options & FTDF_TRANSPARENT_PASS_ALL_PAN_ID ? 1 : 0)); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSWRONGDADDR, (options & FTDF_TRANSPARENT_PASS_ALL_ADDR ? 1 : 0)); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSBEACONWRONGPANID, |
| (options & FTDF_TRANSPARENT_PASS_ALL_BEACON ? 1 : 0)); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSTOPANCOORDINATOR, |
| (options & FTDF_TRANSPARENT_PASS_ALL_NO_DEST_ADDR ? 1 : 0)); |
| } |
| else |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSFRMTYPE, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_DISRXACKREQUESTCA, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSCRCERROR, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSRESFRAMEVERSION, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSWRONGDPANID, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSWRONGDADDR, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSBEACONWRONGPANID, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACALWAYSPASSTOPANCOORDINATOR, 0); |
| } |
| } |
| |
| #if FTDF_DBG_BUS_ENABLE |
| void FTDF_checkDbgMode(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_DBG_CONTROL, FTDF_dbgMode); |
| |
| if (FTDF_dbgMode) |
| { |
| FTDF_DBG_BUS_GPIO_CONFIG(); |
| } |
| } |
| |
| void FTDF_setDbgMode(FTDF_DbgMode dbgMode) |
| { |
| FTDF_dbgMode = dbgMode; |
| FTDF_checkDbgMode(); |
| } |
| #endif /* FTDF_DBG_BUS_ENABLE */ |
| |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_CSL |
| void FTDF_setPeerCslTiming(FTDF_IEList *headerIEList, FTDF_Time timeStamp) |
| { |
| if (FTDF_reqCurrent->msgId != FTDF_DATA_REQUEST) |
| { |
| // Only use the CSL timing of data frame acks |
| return; |
| } |
| |
| FTDF_DataRequest *dataRequest = (FTDF_DataRequest *) FTDF_reqCurrent; |
| FTDF_ShortAddress dstAddr = dataRequest->dstAddr.shortAddress; |
| |
| if (dataRequest->dstAddrMode != FTDF_SHORT_ADDRESS || |
| dstAddr == 0xffff) |
| { |
| return; |
| } |
| |
| int n; |
| |
| // Search for an existing entry |
| for (n = 0; n < FTDF_NR_OF_CSL_PEERS; n++) |
| { |
| if (FTDF_peerCslTiming[ n ].addr == dstAddr) |
| { |
| break; |
| } |
| } |
| |
| if (headerIEList == NULL) |
| { |
| if (n < FTDF_NR_OF_CSL_PEERS) |
| { |
| // Delete entry |
| FTDF_peerCslTiming[ n ].addr = 0xffff; |
| } |
| |
| return; |
| } |
| |
| int ieNr = 0; |
| |
| while (ieNr < headerIEList->nrOfIEs && |
| headerIEList->IEs[ ieNr ].ID != 0x1a) |
| { |
| ieNr++; |
| } |
| |
| if (ieNr == headerIEList->nrOfIEs) |
| { |
| return; |
| } |
| |
| if (n == FTDF_NR_OF_CSL_PEERS) |
| { |
| // Search for an empty entry |
| for (n = 0; n < FTDF_NR_OF_CSL_PEERS; n++) |
| { |
| if (FTDF_peerCslTiming[ n ].addr == 0xffff) |
| { |
| break; |
| } |
| } |
| } |
| |
| if (n == FTDF_NR_OF_CSL_PEERS) |
| { |
| // No free entry, search for the least recently used entry |
| FTDF_Time maxDelta = 0; |
| int lru = 0; |
| |
| for (n = 0; n < FTDF_NR_OF_CSL_PEERS; n++) |
| { |
| FTDF_Time delta = timeStamp - FTDF_peerCslTiming[ n ].time; |
| |
| if (delta > maxDelta) |
| { |
| maxDelta = delta; |
| lru = n; |
| } |
| } |
| |
| n = lru; |
| } |
| |
| FTDF_Period phase = (*(FTDF_Period *)(headerIEList->IEs[ 0 ].content.raw + 0)); |
| FTDF_Period period = (*(FTDF_Period *)(headerIEList->IEs[ 0 ].content.raw + 2)); |
| |
| FTDF_peerCslTiming[ n ].addr = dstAddr; |
| FTDF_peerCslTiming[ n ].time = timeStamp - (phase * 10); |
| FTDF_peerCslTiming[ n ].period = period; |
| } |
| |
| void FTDF_getWakeupParams(FTDF_ShortAddress dstAddr, |
| FTDF_Time *wakeupStartTime, |
| FTDF_Period *wakeupPeriod) |
| { |
| int n; |
| |
| for (n = 0; n < FTDF_NR_OF_CSL_PEERS; n++) |
| { |
| if (FTDF_peerCslTiming[ n ].addr == dstAddr) |
| { |
| break; |
| } |
| } |
| |
| FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| |
| if (dstAddr == 0xffff || |
| n == FTDF_NR_OF_CSL_PEERS) |
| { |
| *wakeupStartTime = curTime + 5; |
| *wakeupPeriod = FTDF_pib.CSLMaxPeriod; |
| |
| return; |
| } |
| |
| FTDF_Time peerTime = FTDF_peerCslTiming[ n ].time; |
| FTDF_Time peerPeriod = FTDF_peerCslTiming[ n ].period * 10; |
| FTDF_Time delta = curTime - peerTime; |
| |
| if (delta > (uint32_t)(FTDF_pib.CSLMaxAgeRemoteInfo * 10)) |
| { |
| *wakeupStartTime = curTime + 5; |
| *wakeupPeriod = FTDF_pib.CSLMaxPeriod; |
| |
| return; |
| } |
| |
| FTDF_Time wStart = peerTime + (((delta / peerPeriod) + 1) * peerPeriod) - FTDF_pib.CSLSyncTxMargin; |
| delta = wStart - curTime; |
| |
| if (delta < 3 || delta > 0x80000000) // A delta larger than 0x80000000 is assumed a negative delta |
| { |
| wStart += peerPeriod; |
| } |
| |
| *wakeupPeriod = (FTDF_pib.CSLSyncTxMargin / 10) * 2; |
| *wakeupStartTime = wStart; |
| } |
| |
| void FTDF_setCslSampleTime(void) |
| { |
| FTDF_Time CSLPeriod = FTDF_pib.CSLPeriod * 10; |
| |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| |
| FTDF_Time curTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| FTDF_Time delta = (curTime - FTDF_startCslSampleTime); |
| |
| // A delta larger than 0x80000000 is assumed a negative delta, in this case the sample time does |
| // not need to be updated. |
| if (delta < 0x80000000) |
| { |
| if (delta < CSLPeriod) |
| { |
| FTDF_startCslSampleTime += CSLPeriod; |
| |
| if (delta < 3) |
| { |
| // To avoid to set the CSL sample time to a time stamp in the past set it to a sample period later |
| // if the next sample would be within 3 symbols. |
| FTDF_startCslSampleTime += CSLPeriod; |
| } |
| } |
| else |
| { |
| FTDF_startCslSampleTime = FTDF_startCslSampleTime + ((delta / CSLPeriod) + 1) * CSLPeriod; |
| } |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLSTARTSAMPLETIME, FTDF_startCslSampleTime); |
| } |
| |
| FTDF_exitCritical(); |
| } |
| #endif /* FTDF_NO_CSL */ |
| #endif /* !FTDF_LITE */ |
| |
| FTDF_Time64 FTDF_getCurTime64(void) |
| { |
| FTDF_Time newTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| |
| if (newTime < FTDF_curTime[ 0 ]) |
| { |
| FTDF_curTime[ 1 ]++; |
| } |
| |
| FTDF_curTime[ 0 ] = newTime; |
| |
| return *(FTDF_Time64 *)FTDF_curTime; |
| } |
| |
| void FTDF_initCurTime64(void) |
| { |
| FTDF_curTime[ 0 ] = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| FTDF_curTime[ 1 ] = 0; |
| } |
| |
| void FTDF_getExtAddress(void) |
| { |
| uint32_t *extAddress = (uint32_t *) &FTDF_pib.extAddress; |
| extAddress[ 0 ] = FTDF_GET_FIELD(ON_OFF_REGMAP_AEXTENDEDADDRESS_L); |
| extAddress[ 1 ] = FTDF_GET_FIELD(ON_OFF_REGMAP_AEXTENDEDADDRESS_H); |
| } |
| |
| void FTDF_setExtAddress(void) |
| { |
| uint32_t *extAddress = (uint32_t *) &FTDF_pib.extAddress; |
| FTDF_SET_FIELD(ON_OFF_REGMAP_AEXTENDEDADDRESS_L, extAddress[ 0 ]); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_AEXTENDEDADDRESS_H, extAddress[ 1 ]); |
| } |
| |
| void FTDF_getAckWaitDuration(void) |
| { |
| FTDF_pib.ackWaitDuration = FTDF_GET_FIELD(ON_OFF_REGMAP_MACACKWAITDURATION); |
| } |
| |
| #ifndef FTDF_LITE |
| void FTDF_getEnhAckWaitDuration(void) |
| { |
| FTDF_pib.enhAckWaitDuration = FTDF_GET_FIELD(ON_OFF_REGMAP_MACENHACKWAITDURATION); |
| } |
| |
| void FTDF_setEnhAckWaitDuration(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACENHACKWAITDURATION, FTDF_pib.enhAckWaitDuration); |
| } |
| |
| void FTDF_getImplicitBroadcast(void) |
| { |
| FTDF_pib.implicitBroadcast = FTDF_GET_FIELD(ON_OFF_REGMAP_MACIMPLICITBROADCAST); |
| } |
| |
| void FTDF_setImplicitBroadcast(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACIMPLICITBROADCAST, FTDF_pib.implicitBroadcast); |
| } |
| #endif /* !FTDF_LITE */ |
| |
| void FTDF_setShortAddress(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACSHORTADDRESS, FTDF_pib.shortAddress); |
| } |
| |
| #ifndef FTDF_LITE |
| void FTDF_setSimpleAddress(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACSIMPLEADDRESS, FTDF_pib.simpleAddress); |
| } |
| #endif /* !FTDF_LITE */ |
| |
| void FTDF_getRxOnWhenIdle(void) |
| { |
| FTDF_pib.rxOnWhenIdle = FTDF_GET_FIELD(ON_OFF_REGMAP_RXALWAYSON); |
| } |
| |
| void FTDF_setRxOnWhenIdle(void) |
| { |
| #if FTDF_USE_PTI && !FTDF_USE_AUTO_PTI |
| /* We do not force decision here. It will be automatically made when FTDF begins |
| * transaction. |
| */ |
| hw_coex_update_ftdf_pti((hw_coex_pti_t) FTDF_getRxPti(), NULL, false); |
| #endif /* FTDF_USE_PTI && !FTDF_USE_AUTO_PTI */ |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXALWAYSON, FTDF_pib.rxOnWhenIdle); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_RXENABLE, 1); |
| |
| } |
| |
| void FTDF_getPANId(void) |
| { |
| FTDF_pib.PANId = FTDF_GET_FIELD(ON_OFF_REGMAP_MACPANID); |
| } |
| |
| void FTDF_setPANId(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACPANID, FTDF_pib.PANId); |
| } |
| |
| void FTDF_getCurrentChannel(void) |
| { |
| FTDF_pib.currentChannel = ((FTDF_GET_FIELD(ON_OFF_REGMAP_PHYRXATTR) & 0x00f0) >> 4) + 11; |
| } |
| |
| void FTDF_setCurrentChannel(void) |
| { |
| uint32_t phyAckAttr = 0x08 | ((FTDF_pib.currentChannel - 11) & 0xf) << 4 | (FTDF_pib.TXPower & 0x7) << 12; |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_PHYRXATTR, (((FTDF_pib.currentChannel - 11) & 0xf) << 4)); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_PHYACKATTR, phyAckAttr); |
| } |
| |
| void FTDF_setTXPower(void) |
| { |
| /* Just like setCurrentChannel, this sets pyAckAttr */ |
| uint32_t phyAckAttr = 0x08 | ((FTDF_pib.currentChannel - 11) & 0xf) << 4 | (FTDF_pib.TXPower & 0x7) << 12; |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_PHYACKATTR, phyAckAttr); |
| } |
| |
| void FTDF_getMaxFrameTotalWaitTime(void) |
| { |
| FTDF_pib.maxFrameTotalWaitTime = FTDF_GET_FIELD(ON_OFF_REGMAP_MACMAXFRAMETOTALWAITTIME); |
| } |
| |
| void FTDF_setMaxFrameTotalWaitTime(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACMAXFRAMETOTALWAITTIME, FTDF_pib.maxFrameTotalWaitTime); |
| } |
| |
| void FTDF_setMaxCSMABackoffs(void) |
| { |
| #ifndef FTDF_LITE |
| |
| if (FTDF_pib.leEnabled == FTDF_FALSE && FTDF_pib.tschEnabled == FTDF_FALSE) |
| #endif /* !FTDF_LITE */ |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACMAXCSMABACKOFFS, FTDF_pib.maxCSMABackoffs); |
| } |
| } |
| |
| void FTDF_setMaxBE(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACMAXBE, FTDF_pib.maxBE); |
| } |
| |
| void FTDF_setMinBE(void) |
| { |
| #ifndef FTDF_LITE |
| |
| if (FTDF_pib.leEnabled == FTDF_FALSE && FTDF_pib.tschEnabled == FTDF_FALSE) |
| #endif /* !FTDF_LITE */ |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACMINBE, FTDF_pib.minBE); |
| } |
| } |
| |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_CSL |
| void FTDF_setLeEnabled(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLSAMPLEPERIOD, 66); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLDATAPERIOD, 66); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLMARGINRZ, 1); |
| |
| if (FTDF_pib.leEnabled) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACMAXCSMABACKOFFS, 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACMINBE, 0); |
| |
| if (FTDF_oldLeEnabled == FTDF_FALSE) |
| { |
| if (FTDF_wakeUpEnableLe == FTDF_FALSE) |
| { |
| FTDF_startCslSampleTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| FTDF_setCslSampleTime(); |
| } |
| else |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLSTARTSAMPLETIME, FTDF_startCslSampleTime); |
| } |
| } |
| } |
| else |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACMAXCSMABACKOFFS, FTDF_pib.maxCSMABackoffs); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACMINBE, FTDF_pib.minBE); |
| } |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACLEENABLED, FTDF_pib.leEnabled); |
| |
| FTDF_oldLeEnabled = FTDF_pib.leEnabled; |
| } |
| |
| void FTDF_getCslFramePendingWaitT(void) |
| { |
| FTDF_pib.CSLFramePendingWaitT = FTDF_GET_FIELD(ON_OFF_REGMAP_MACCSLFRAMEPENDINGWAITT); |
| } |
| |
| void FTDF_setCslFramePendingWaitT(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACCSLFRAMEPENDINGWAITT, FTDF_pib.CSLFramePendingWaitT); |
| } |
| #endif /* FTDF_NO_CSL */ |
| #endif /* !FTDF_LITE */ |
| |
| void FTDF_getLmacPmData(void) |
| { |
| FTDF_pib.performanceMetrics.FCSErrorCount = FTDF_GET_FIELD(ON_OFF_REGMAP_MACFCSERRORCOUNT) + |
| FTDF_lmacCounters.fcsErrorCnt; |
| } |
| |
| void FTDF_getLmacTrafficCounters(void) |
| { |
| FTDF_pib.trafficCounters.txStdAckFrmCnt = FTDF_GET_FIELD(ON_OFF_REGMAP_MACTXSTDACKFRMCNT) + |
| FTDF_lmacCounters.txStdAckCnt; |
| FTDF_pib.trafficCounters.rxStdAckFrmOkCnt = FTDF_GET_FIELD(ON_OFF_REGMAP_MACRXSTDACKFRMOKCNT) + |
| FTDF_lmacCounters.rxStdAckCnt; |
| } |
| |
| void FTDF_getKeepPhyEnabled(void) |
| { |
| FTDF_pib.keepPhyEnabled = FTDF_GET_FIELD(ON_OFF_REGMAP_KEEP_PHY_EN); |
| } |
| |
| void FTDF_setKeepPhyEnabled(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_KEEP_PHY_EN, FTDF_pib.keepPhyEnabled); |
| } |
| |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| void FTDF_setBoIrqThreshold(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_CSMA_CA_BO_THRESHOLD, FTDF_pib.boIrqThreshold); |
| } |
| void FTDF_getBoIrqThreshold(void) |
| { |
| FTDF_pib.boIrqThreshold = FTDF_GET_FIELD(ON_OFF_REGMAP_CSMA_CA_BO_THRESHOLD); |
| } |
| void FTDF_setPtiConfig(void) |
| { |
| FTDF_SET_FIELD_INDEXED(ON_OFF_REGMAP_PTI_TX, FTDF_pib.ptiConfig.ptis[FTDF_PTI_CONFIG_TX], |
| FTDF_TX_DATA_BUFFER); |
| FTDF_SET_FIELD_INDEXED(ON_OFF_REGMAP_PTI_TX, FTDF_pib.ptiConfig.ptis[FTDF_PTI_CONFIG_TX], |
| FTDF_TX_WAKEUP_BUFFER); |
| FTDF_SET_FIELD_INDEXED(ON_OFF_REGMAP_PTI_TX, FTDF_pib.ptiConfig.ptis[FTDF_PTI_CONFIG_RX], |
| FTDF_TX_ACK_BUFFER); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_PTI_RX, FTDF_pib.ptiConfig.ptis[FTDF_PTI_CONFIG_RX]); |
| } |
| #endif /* #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */ |
| |
| #ifndef FTDF_LITE |
| #ifndef FTDF_NO_TSCH |
| void FTDF_setTimeslotTemplate(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACTSTXACKDELAY, FTDF_pib.timeslotTemplate.tsTxAckDelay); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACTSRXWAIT, FTDF_pib.timeslotTemplate.tsRxWait); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACTSRXACKDELAY, FTDF_pib.timeslotTemplate.tsRxAckDelay); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACTSACKWAIT, FTDF_pib.timeslotTemplate.tsAckWait); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_MACTSRXTX, FTDF_pib.timeslotTemplate.tsRxTx - |
| FTDF_PHYTRXWAIT - FTDF_PHYTXSTARTUP - FTDF_PHYTXLATENCY); |
| } |
| #endif /* FTDF_NO_TSCH */ |
| #endif /* !FTDF_LITE */ |
| |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| #if FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO |
| /************************************ FPPR common functions ***************************************/ |
| #ifndef FTDF_LITE |
| |
| FTDF_Boolean FTDF_fpFsmShortAddressNew(FTDF_PANId panId, FTDF_ShortAddress shortAddress) |
| { |
| uint8_t entry; |
| uint8_t shortAddrIdx; |
| |
| if (FTDF_fpprGetFreeShortAddress(&entry, &shortAddrIdx) == FTDF_FALSE) |
| { |
| return FTDF_FALSE; |
| } |
| |
| FTDF_fpprSetShortAddress(entry, shortAddrIdx, shortAddress); |
| FTDF_fpprSetShortAddressValid(entry, shortAddrIdx, FTDF_TRUE); |
| |
| return FTDF_TRUE; |
| } |
| |
| FTDF_Boolean FTDF_fpFsmExtAddressNew(FTDF_PANId panId, FTDF_ExtAddress extAddress) |
| { |
| uint8_t entry; |
| |
| if (FTDF_fpprGetFreeExtAddress(&entry) == FTDF_FALSE) |
| { |
| return FTDF_FALSE; |
| } |
| |
| FTDF_fpprSetExtAddress(entry, extAddress); |
| FTDF_fpprSetExtAddressValid(entry, FTDF_TRUE); |
| |
| return FTDF_TRUE; |
| } |
| |
| void FTDF_fpFsmShortAddressLastFramePending(FTDF_PANId PANId, FTDF_ShortAddress shortAddress) |
| { |
| #if FTDF_FPPR_DEFER_INVALIDATION |
| FTDF_fpprPending.addrMode = FTDF_SHORT_ADDRESS; |
| FTDF_fpprPending.PANId = PANId; |
| FTDF_fpprPending.addr.shortAddress = shortAddress; |
| #else /* FTDF_FPPR_DEFER_INVALIDATION */ |
| uint8_t entry; |
| uint8_t shortAddrIdx; |
| FTDF_Boolean found = FTDF_fpprLookupShortAddress(shortAddress, &entry, &shortAddrIdx); |
| ASSERT_WARNING(found); |
| FTDF_fpprSetShortAddressValid(entry, shortAddrIdx, FTDF_FALSE); |
| #endif /* FTDF_FPPR_DEFER_INVALIDATION */ |
| } |
| |
| void FTDF_fpFsmExtAddressLastFramePending(FTDF_PANId PANId, FTDF_ExtAddress extAddress) |
| { |
| #if FTDF_FPPR_DEFER_INVALIDATION |
| FTDF_fpprPending.addrMode = FTDF_EXTENDED_ADDRESS; |
| FTDF_fpprPending.PANId = PANId; |
| FTDF_fpprPending.addr.extAddress = extAddress; |
| #else /* FTDF_FPPR_DEFER_INVALIDATION */ |
| uint8_t entry; |
| FTDF_Boolean found = FTDF_fpprLookupExtAddress(extAddress, &entry); |
| ASSERT_WARNING(found); |
| FTDF_fpprSetExtAddressValid(entry, FTDF_FALSE); |
| #endif /* FTDF_FPPR_DEFER_INVALIDATION */ |
| } |
| |
| void FTDF_fpFsmClearPending(void) |
| { |
| #if FTDF_FPPR_DEFER_INVALIDATION |
| int n; |
| |
| if (FTDF_fpprPending.addrMode == FTDF_NO_ADDRESS) |
| { |
| return; |
| } |
| |
| if (FTDF_fpprPending.addrMode == FTDF_SHORT_ADDRESS) |
| { |
| for (n = 0; n < FTDF_NR_OF_REQ_BUFFERS; n++) |
| { |
| if (FTDF_txPendingList[ n ].addrMode == FTDF_SHORT_ADDRESS) |
| { |
| if ((FTDF_txPendingList[ n ].PANId == FTDF_fpprPending.PANId) && |
| (FTDF_txPendingList[ n ].addr.shortAddress == |
| FTDF_fpprPending.addr.shortAddress)) |
| { |
| return; |
| } |
| } |
| } |
| |
| // Address not found. |
| uint8_t entry; |
| uint8_t shortAddrIdx; |
| FTDF_Boolean found = FTDF_fpprLookupShortAddress( |
| FTDF_fpprPending.addr.shortAddress, &entry, &shortAddrIdx); |
| ASSERT_WARNING(found); |
| FTDF_fpprSetShortAddressValid(entry, shortAddrIdx, FTDF_FALSE); |
| } |
| else if (FTDF_fpprPending.addrMode == FTDF_EXTENDED_ADDRESS) |
| { |
| for (n = 0; n < FTDF_NR_OF_REQ_BUFFERS; n++) |
| { |
| if (FTDF_txPendingList[ n ].addrMode == FTDF_EXTENDED_ADDRESS) |
| { |
| if (FTDF_txPendingList[ n ].addr.extAddress == |
| FTDF_fpprPending.addr.extAddress) |
| { |
| return; |
| } |
| } |
| } |
| |
| // Address not found. |
| uint8_t entry; |
| FTDF_Boolean found = FTDF_fpprLookupExtAddress(FTDF_fpprPending.addr.extAddress, |
| &entry); |
| ASSERT_WARNING(found); |
| FTDF_fpprSetExtAddressValid(entry, FTDF_FALSE); |
| } |
| else |
| { |
| |
| } |
| |
| FTDF_fpprPending.addrMode = FTDF_NO_ADDRESS; |
| #endif /* FTDF_FPPR_DEFER_INVALIDATION */ |
| } |
| |
| #endif /* #ifndef FTDF_LITE */ |
| /*********************************** FPPR low-level access ****************************************/ |
| void FTDF_fpprReset(void) |
| { |
| unsigned int i; |
| |
| for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++) |
| { |
| *FTDF_GET_REG_ADDR_INDEXED(FP_PROCESSING_RAM_SIZE_AND_VAL, i) = 0; |
| } |
| } |
| |
| FTDF_ShortAddress FTDF_fpprGetShortAddress(uint8_t entry, uint8_t shortAddrIdx) |
| { |
| ASSERT_WARNING(entry < FTDF_FPPR_TABLE_ENTRIES); |
| |
| switch (shortAddrIdx) |
| { |
| case 0: |
| return (FTDF_ShortAddress) |
| * FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, entry) & |
| 0x0000ffff; |
| |
| case 1: |
| return (FTDF_ShortAddress) |
| (*FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, entry) >> 16) & |
| 0x0000ffff; |
| |
| case 2: |
| return (FTDF_ShortAddress) |
| * FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, entry) & |
| 0x0000ffff; |
| |
| case 3: |
| return (FTDF_ShortAddress) |
| (*FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, entry) >> 16) & |
| 0x0000ffff; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| } |
| |
| void FTDF_fpprSetShortAddress(uint8_t entry, uint8_t shortAddrIdx, |
| FTDF_ShortAddress shortAddress) |
| { |
| ASSERT_WARNING(entry < FTDF_FPPR_TABLE_ENTRIES); |
| uint32_t val32; |
| |
| switch (shortAddrIdx) |
| { |
| case 0: |
| val32 = *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, entry); |
| val32 &= 0xffff0000; |
| val32 |= (shortAddress & 0x0000ffff); |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, entry) = val32; |
| break; |
| |
| case 1: |
| val32 = *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, entry); |
| val32 &= 0x0000ffff; |
| val32 |= (shortAddress & 0x0000ffff) << 16; |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, entry) = val32; |
| break; |
| |
| case 2: |
| val32 = *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, entry); |
| val32 &= 0xffff0000; |
| val32 |= (shortAddress & 0x0000ffff); |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, entry) = val32; |
| break; |
| |
| case 3: |
| val32 = *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, entry); |
| val32 &= 0x0000ffff; |
| val32 |= (shortAddress & 0x0000ffff) << 16; |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, entry) = val32; |
| break; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| } |
| |
| FTDF_Boolean FTDF_fpprGetShortAddressValid(uint8_t entry, uint8_t shortAddrIdx) |
| { |
| ASSERT_WARNING(entry < FTDF_FPPR_TABLE_ENTRIES); |
| ASSERT_WARNING(shortAddrIdx < 4); |
| uint32_t val32; |
| val32 = *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_VALID_SA, entry); |
| return ((val32 & (MSK_F_FTDF_FP_PROCESSING_RAM_SHORT_LONGNOT | (1 << shortAddrIdx))) == |
| (MSK_F_FTDF_FP_PROCESSING_RAM_SHORT_LONGNOT | (1 << shortAddrIdx))) ? |
| FTDF_TRUE : FTDF_FALSE; |
| } |
| |
| void FTDF_fpprSetShortAddressValid(uint8_t entry, uint8_t shortAddrIdx, |
| FTDF_Boolean valid) |
| { |
| ASSERT_WARNING(entry < FTDF_FPPR_TABLE_ENTRIES); |
| ASSERT_WARNING(shortAddrIdx < 4); |
| uint32_t val32; |
| val32 = *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_VALID_SA, entry); |
| |
| if (valid) |
| { |
| val32 |= MSK_F_FTDF_FP_PROCESSING_RAM_SHORT_LONGNOT | (1 << shortAddrIdx); /* Also indicate short address. */ |
| } |
| else |
| { |
| val32 &= ~(1 << shortAddrIdx); |
| } |
| |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_VALID_SA, entry) = val32; |
| } |
| |
| FTDF_ExtAddress FTDF_fpprGetExtAddress(uint8_t entry) |
| { |
| FTDF_ExtAddress extAddress; |
| ASSERT_WARNING(entry < FTDF_FPPR_TABLE_ENTRIES); |
| extAddress = (FTDF_ExtAddress) * FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, |
| entry) << 32; |
| extAddress |= (FTDF_ExtAddress) * FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, |
| entry); |
| return extAddress; |
| } |
| |
| void FTDF_fpprSetExtAddress(uint8_t entry, FTDF_ExtAddress extAddress) |
| { |
| ASSERT_WARNING(entry < FTDF_FPPR_TABLE_ENTRIES); |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, entry) = |
| (uint32_t)(extAddress); |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, entry) = |
| (uint32_t)((extAddress >> 32)); |
| } |
| |
| FTDF_Boolean FTDF_fpprGetExtAddressValid(uint8_t entry) |
| { |
| return (*FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_VALID_SA, entry) == 0x1) ? |
| FTDF_TRUE : FTDF_FALSE; |
| } |
| |
| void FTDF_fpprSetExtAddressValid(uint8_t entry, FTDF_Boolean valid) |
| { |
| ASSERT_WARNING(entry < FTDF_FPPR_TABLE_ENTRIES); |
| |
| if (valid) |
| { |
| /* Also indicate ext address. */ |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_VALID_SA, entry) = 0x1; |
| } |
| else |
| { |
| *FTDF_GET_FIELD_ADDR_INDEXED(FP_PROCESSING_RAM_VALID_SA, entry) = 0x0; |
| } |
| } |
| |
| FTDF_Boolean FTDF_fpprGetFreeShortAddress(uint8_t *entry, uint8_t *shortAddrIdx) |
| { |
| int i, j; |
| uint32_t sizeAndVal; |
| int emptyEntry; |
| bool emptyFound = false, nonEmptyFound = false; |
| |
| for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++) |
| { |
| sizeAndVal = *FTDF_GET_REG_ADDR_INDEXED(FP_PROCESSING_RAM_SIZE_AND_VAL, i); |
| |
| if (sizeAndVal == 0x1) |
| { |
| /* Check if there is a valid extended address. */ |
| continue; |
| } |
| else if ((sizeAndVal & MSK_F_FTDF_FP_PROCESSING_RAM_SHORT_LONGNOT) == 0) |
| { |
| /* There is an invalid extended address, ignore SA valid bits */ |
| sizeAndVal = 0; |
| } |
| else |
| { |
| /* There is a SA. We are interested in bits V0 - V3. */ |
| sizeAndVal &= 0xf; |
| } |
| |
| /* Check if entire entry is free. */ |
| if (sizeAndVal == 0) |
| { |
| /* We prefer to use partially full entries. Make note of this and |
| * continue. */ |
| if (!emptyFound) |
| { |
| emptyEntry = i; |
| emptyFound = true; |
| } |
| |
| continue; |
| } |
| |
| /* Check for free short address entries. */ |
| sizeAndVal = (~sizeAndVal) & 0xf; |
| j = 0; |
| |
| while (sizeAndVal) |
| { |
| if (sizeAndVal & 0x1) |
| { |
| nonEmptyFound = true; |
| break; |
| } |
| |
| sizeAndVal >>= 1; |
| j++; |
| } |
| |
| if (nonEmptyFound) |
| { |
| break; |
| } |
| } |
| |
| if (nonEmptyFound) |
| { |
| *entry = i; |
| *shortAddrIdx = j; |
| } |
| else if (emptyFound) |
| { |
| *entry = emptyEntry; |
| *shortAddrIdx = 0; |
| } |
| else |
| { |
| return FTDF_FALSE; |
| } |
| |
| return FTDF_TRUE; |
| } |
| |
| FTDF_Boolean FTDF_fpprGetFreeExtAddress(uint8_t *entry) |
| { |
| int i; |
| uint32_t sizeAndVal; |
| bool found = false; |
| |
| for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++) |
| { |
| sizeAndVal = *FTDF_GET_REG_ADDR_INDEXED(FP_PROCESSING_RAM_SIZE_AND_VAL, i); |
| |
| /* Check if there is no valid extended or short address. */ |
| if (!sizeAndVal || (sizeAndVal == MSK_F_FTDF_FP_PROCESSING_RAM_SHORT_LONGNOT)) |
| { |
| found = true; |
| break; |
| } |
| } |
| |
| if (found) |
| { |
| *entry = i; |
| } |
| else |
| { |
| return FTDF_FALSE; |
| } |
| |
| return FTDF_TRUE; |
| } |
| |
| FTDF_Boolean FTDF_fpprLookupShortAddress(FTDF_ShortAddress shortAddr, uint8_t *entry, |
| uint8_t *shortAddrIdx) |
| { |
| uint8_t i; |
| uint32_t sizeAndVal; |
| uint32_t saPart; |
| |
| for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++) |
| { |
| sizeAndVal = *FTDF_GET_REG_ADDR_INDEXED(FP_PROCESSING_RAM_SIZE_AND_VAL, i); |
| |
| /* Check if there is a valid short address. */ |
| if (!(sizeAndVal & MSK_F_FTDF_FP_PROCESSING_RAM_SHORT_LONGNOT) || |
| !(sizeAndVal & MSK_F_FTDF_FP_PROCESSING_RAM_VALID_SA)) |
| { |
| continue; |
| } |
| |
| saPart = FTDF_GET_FIELD_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, i); |
| |
| if (sizeAndVal & 0x1) |
| { |
| if (shortAddr == (FTDF_ShortAddress)(saPart & 0x0000ffff)) |
| { |
| *entry = i; |
| *shortAddrIdx = 0; |
| return FTDF_TRUE; |
| } |
| } |
| |
| if (sizeAndVal & 0x2) |
| { |
| if (shortAddr == (FTDF_ShortAddress)((saPart >> 16) & 0x0000ffff)) |
| { |
| *entry = i; |
| *shortAddrIdx = 1; |
| return FTDF_TRUE; |
| } |
| } |
| |
| saPart = FTDF_GET_FIELD_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, i); |
| |
| if (sizeAndVal & 0x4) |
| { |
| if (shortAddr == (FTDF_ShortAddress)(saPart & 0x0000ffff)) |
| { |
| *entry = i; |
| *shortAddrIdx = 2; |
| return FTDF_TRUE; |
| } |
| } |
| |
| if (sizeAndVal & 0x8) |
| { |
| if (shortAddr == ((FTDF_ShortAddress)(saPart >> 16) & 0x0000ffff)) |
| { |
| *entry = i; |
| *shortAddrIdx = 3; |
| return FTDF_TRUE; |
| } |
| } |
| } |
| |
| return FTDF_FALSE; |
| } |
| |
| FTDF_Boolean FTDF_fpprLookupExtAddress(FTDF_ExtAddress extAddr, uint8_t *entry) |
| { |
| uint8_t i; |
| uint32_t sizeAndVal; |
| uint32_t extAddrHi, extAddrLo; |
| extAddrHi = (uint32_t)((extAddr >> 32) & 0xffffffff); |
| extAddrLo = (uint32_t)(extAddr & 0xffffffff); |
| |
| for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++) |
| { |
| sizeAndVal = *FTDF_GET_REG_ADDR_INDEXED(FP_PROCESSING_RAM_SIZE_AND_VAL, i); |
| |
| /* Check if there is a valid extended address. */ |
| if (sizeAndVal != 0x1) |
| { |
| continue; |
| } |
| |
| if ((extAddrLo == FTDF_GET_FIELD_INDEXED(FP_PROCESSING_RAM_EXP_SA_L, i)) && |
| (extAddrHi == FTDF_GET_FIELD_INDEXED(FP_PROCESSING_RAM_EXP_SA_H, i))) |
| { |
| *entry = i; |
| return FTDF_TRUE; |
| } |
| } |
| |
| return FTDF_FALSE; |
| } |
| |
| #endif /* FTDF_FP_BIT_MODE == FTDF_FP_BIT_MODE_AUTO */ |
| |
| void FTDF_fpprSetMode(FTDF_Boolean matchFp, FTDF_Boolean fpOverride, FTDF_Boolean fpForce) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_ADDR_TAB_MATCH_FP_VALUE, matchFp ? 1 : 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_FP_OVERRIDE, fpOverride ? 1 : 0); |
| FTDF_SET_FIELD(ON_OFF_REGMAP_FP_FORCE_VALUE, fpForce ? 1 : 0); |
| } |
| |
| #if FTDF_FP_BIT_TEST_MODE |
| void FTDF_fpprGetMode(FTDF_Boolean *matchFp, FTDF_Boolean *fpOverride, FTDF_Boolean *fpForce) |
| { |
| *matchFp = FTDF_GET_FIELD(ON_OFF_REGMAP_ADDR_TAB_MATCH_FP_VALUE) ? FTDF_TRUE : FTDF_FALSE; |
| *fpOverride = FTDF_GET_FIELD(ON_OFF_REGMAP_FP_OVERRIDE) ? FTDF_TRUE : FTDF_FALSE; |
| *fpForce = FTDF_GET_FIELD(ON_OFF_REGMAP_FP_FORCE_VALUE) ? FTDF_TRUE : FTDF_FALSE; |
| } |
| #endif // FTDF_FP_BIT_TEST_MODE |
| |
| void FTDF_lpdpEnable(FTDF_Boolean enable) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_FTDF_LPDP_ENABLE, enable ? 1 : 0); |
| } |
| |
| #if FTDF_FP_BIT_TEST_MODE |
| FTDF_Boolean FTDF_lpdpIsEnabled(void) |
| { |
| return FTDF_GET_FIELD(ON_OFF_REGMAP_FTDF_LPDP_ENABLE) ? FTDF_TRUE : FTDF_FALSE; |
| } |
| #endif |
| |
| #if FTDF_USE_SLEEP_DURING_BACKOFF |
| |
| static inline void FTDF_sdbSaveState(void) |
| { |
| volatile uint32_t *txFifoPtr = FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO); |
| uint32_t *dstPtr = (uint32_t *) FTDF_sdb.buffer; |
| uint8_t word_length_rem; |
| |
| FTDF_sdb.nrOfBackoffs = FTDF_GET_FIELD(ON_OFF_REGMAP_CSMA_CA_NB_STAT); |
| |
| /* Read first 4 bytes. */ |
| *dstPtr++ = *txFifoPtr++; |
| |
| ASSERT_WARNING((FTDF_sdb.buffer[0] >= 3) && (FTDF_sdb.buffer[0] < FTDF_BUFFER_LENGTH)); |
| /* The length is the buffer length excluding the length byte itself */ |
| word_length_rem = (FTDF_sdb.buffer[0] + 4) / 4 - 1; /* 1 word we already read */ |
| |
| while (word_length_rem--) |
| { |
| *dstPtr++ = *txFifoPtr++; |
| } |
| |
| FTDF_sdb.metadata0 = *FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_0, |
| FTDF_TX_DATA_BUFFER); |
| FTDF_sdb.metadata1 = *FTDF_GET_REG_ADDR_INDEXED(RETENTION_RAM_TX_META_DATA_1, |
| FTDF_TX_DATA_BUFFER); |
| FTDF_sdb.phyCsmaCaAttr = FTDF_GET_FIELD(ON_OFF_REGMAP_PHYCSMACAATTR); |
| } |
| |
| static inline void FTDF_sdbResume(void) |
| { |
| volatile uint32_t *txFifoPtr = FTDF_GET_REG_ADDR(RETENTION_RAM_TX_FIFO); |
| volatile uint32_t *txFlagSet = FTDF_GET_FIELD_ADDR(ON_OFF_REGMAP_TX_FLAG_SET); |
| uint32_t *srcPtr = (uint32_t *) FTDF_sdb.buffer; |
| |
| uint8_t word_length_rem; |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_CSMA_CA_NB_VAL, FTDF_sdb.nrOfBackoffs); |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_CSMA_CA_RESUME_SET, 1); |
| |
| ASSERT_WARNING((FTDF_sdb.buffer[0] >= 3) && (FTDF_sdb.buffer[0] < FTDF_BUFFER_LENGTH)); |
| |
| /* The length is the buffer length excluding the length byte itself */ |
| word_length_rem = (FTDF_sdb.buffer[0] + 4) / 4; |
| |
| while (word_length_rem--) |
| { |
| *txFifoPtr++ = *srcPtr++; |
| } |
| |
| FTDF_SET_FIELD(ON_OFF_REGMAP_PHYCSMACAATTR, FTDF_sdb.phyCsmaCaAttr); |
| |
| *FTDF_GET_REG_ADDR(RETENTION_RAM_TX_META_DATA_0) = FTDF_sdb.metadata0; |
| |
| *FTDF_GET_REG_ADDR(RETENTION_RAM_TX_META_DATA_1) = FTDF_sdb.metadata1; |
| |
| *txFlagSet |= (1 << FTDF_TX_DATA_BUFFER); |
| } |
| |
| static inline void FTDF_sdbReset(void) |
| { |
| FTDF_SET_FIELD(ON_OFF_REGMAP_CSMA_CA_RESUME_CLEAR, 1); |
| } |
| |
| static inline void FTDF_sdbSetCCARetryTime(void) |
| { |
| FTDF_Time timestamp = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| FTDF_Time boStat = FTDF_GET_FIELD(ON_OFF_REGMAP_CSMA_CA_BO_STAT) * |
| FTDF_UNIT_BACKOFF_PERIOD; |
| FTDF_sdb.ccaRetryTime = timestamp + boStat; |
| } |
| |
| void FTDF_sdbFsmReset(void) |
| { |
| FTDF_sdbReset(); |
| FTDF_sdb.state = FTDF_SDB_STATE_INIT; |
| } |
| |
| void FTDF_sdbFsmBackoffIRQ(void) |
| { |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| |
| if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled) |
| { |
| return; |
| } |
| |
| #endif |
| |
| switch (FTDF_sdb.state) |
| { |
| case FTDF_SDB_STATE_RESUMING: |
| FTDF_sdbReset(); |
| |
| case FTDF_SDB_STATE_INIT: |
| case FTDF_SDB_STATE_BACKING_OFF: |
| FTDF_sdbSetCCARetryTime(); |
| FTDF_sdb.state = FTDF_SDB_STATE_BACKING_OFF; |
| break; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| } |
| |
| void FTDF_sdbFsmSleep(void) |
| { |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| |
| if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled) |
| { |
| return; |
| } |
| |
| #endif |
| |
| switch (FTDF_sdb.state) |
| { |
| case FTDF_SDB_STATE_BACKING_OFF: |
| FTDF_sdbSaveState(); |
| FTDF_sdb.state = FTDF_SDB_STATE_WAITING_WAKE_UP_IRQ; |
| break; |
| |
| case FTDF_SDB_STATE_INIT: |
| break; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| } |
| |
| void FTDF_sdbFsmAbortSleep(void) |
| { |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| |
| if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled) |
| { |
| return; |
| } |
| |
| #endif |
| |
| switch (FTDF_sdb.state) |
| { |
| case FTDF_SDB_STATE_BACKING_OFF: |
| FTDF_sdb.state = FTDF_SDB_STATE_INIT; |
| break; |
| |
| case FTDF_SDB_STATE_INIT: |
| case FTDF_SDB_STATE_WAITING_WAKE_UP_IRQ: |
| case FTDF_SDB_STATE_RESUMING: |
| break; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| } |
| |
| void FTDF_sdbFsmWakeUpIRQ(void) |
| { |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| |
| if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled) |
| { |
| return; |
| } |
| |
| #endif |
| |
| switch (FTDF_sdb.state) |
| { |
| case FTDF_SDB_STATE_WAITING_WAKE_UP_IRQ: |
| FTDF_sdb.state = FTDF_SDB_STATE_RESUMING; |
| break; |
| |
| case FTDF_SDB_STATE_INIT: |
| break; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| } |
| |
| void FTDF_sdbFsmWakeUp(void) |
| { |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| |
| if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled) |
| { |
| return; |
| } |
| |
| #endif |
| |
| switch (FTDF_sdb.state) |
| { |
| case FTDF_SDB_STATE_RESUMING: |
| FTDF_sdbResume(); |
| break; |
| |
| case FTDF_SDB_STATE_WAITING_WAKE_UP_IRQ: |
| break; |
| |
| case FTDF_SDB_STATE_INIT: |
| break; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| } |
| |
| void FTDF_sdbFsmTxIRQ(void) |
| { |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| |
| if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled) |
| { |
| return; |
| } |
| |
| #endif |
| |
| switch (FTDF_sdb.state) |
| { |
| case FTDF_SDB_STATE_RESUMING: |
| FTDF_sdbReset(); |
| FTDF_sdb.state = FTDF_SDB_STATE_INIT; |
| break; |
| |
| case FTDF_SDB_STATE_BACKING_OFF: |
| FTDF_sdb.state = FTDF_SDB_STATE_INIT; |
| break; |
| |
| case FTDF_SDB_STATE_INIT: |
| break; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| } |
| |
| FTDF_USec FTDF_sdbGetSleepTime(void) |
| { |
| FTDF_USec sleepTime = ~((FTDF_USec) 0); |
| #if !defined(FTDF_NO_CSL) || !defined(FTDF_NO_TSCH) |
| |
| if (FTDF_pib.leEnabled || FTDF_pib.tschEnabled) |
| { |
| return sleepTime; |
| } |
| |
| #endif |
| |
| switch (FTDF_sdb.state) |
| { |
| case FTDF_SDB_STATE_INIT: |
| { |
| if ((FTDF_GET_FIELD(ON_OFF_REGMAP_LMACREADY4SLEEP) == 0) || FTDF_reqCurrent) |
| { |
| sleepTime = 0; |
| } |
| else |
| { |
| sleepTime = ~((FTDF_USec) 0); |
| } |
| |
| break; |
| } |
| |
| case FTDF_SDB_STATE_BACKING_OFF: |
| { |
| FTDF_Time currentTime = FTDF_GET_FIELD(ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL); |
| |
| if (currentTime <= FTDF_sdb.ccaRetryTime) |
| { |
| sleepTime = (FTDF_sdb.ccaRetryTime - currentTime) * 16; |
| } |
| else |
| { |
| sleepTime = (1 << SIZE_F_FTDF_ON_OFF_REGMAP_SYMBOLTIMESNAPSHOTVAL - 1) - |
| (currentTime + FTDF_sdb.ccaRetryTime) * 16; |
| } |
| |
| if (sleepTime > 256 * FTDF_UNIT_BACKOFF_PERIOD * 16) |
| { |
| /* We have exceeded the CCA retry time. Abort sleep and wait for Tx IRQ. */ |
| sleepTime = 0; |
| } |
| |
| break; |
| } |
| |
| case FTDF_SDB_STATE_RESUMING: |
| sleepTime = 0; |
| break; |
| |
| case FTDF_SDB_STATE_WAITING_WAKE_UP_IRQ: |
| sleepTime = ~((FTDF_USec) 0); |
| break; |
| |
| default: |
| ASSERT_WARNING(0); |
| } |
| |
| return sleepTime; |
| } |
| |
| #endif /* FTDF_USE_SLEEP_DURING_BACKOFF */ |
| |
| #endif /* #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A */ |
| |
| #if dg_configUSE_FTDF_DDPHY == 1 |
| void FTDF_ddphySet(uint16_t ccaReg) |
| { |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| /* We use the critical section here as protection for the global variable and the HW sleep |
| * state. */ |
| FTDF_ddphyCcaReg = ccaReg; |
| |
| /* Apply immediately if block is up. */ |
| if (REG_GETF(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP) == 0x0) |
| { |
| FTDF_DPHY->DDPHY_CCA_REG = FTDF_ddphyCcaReg; |
| } |
| |
| FTDF_exitCritical(); |
| } |
| |
| void FTDF_ddphyRestore(void) |
| { |
| if (FTDF_ddphyCcaReg) |
| { |
| /* Apply immediately if block is up. */ |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| ASSERT_WARNING(REG_GETF(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP) == 0x0); |
| FTDF_DPHY->DDPHY_CCA_REG = FTDF_ddphyCcaReg; |
| FTDF_exitCritical(); |
| } |
| } |
| |
| void FTDF_ddphySave(void) |
| { |
| /* Apply immediately if block is up. */ |
| FTDF_criticalVar(); |
| FTDF_enterCritical(); |
| ASSERT_WARNING(REG_GETF(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP) == 0x0); |
| FTDF_ddphyCcaReg = FTDF_DPHY->DDPHY_CCA_REG; |
| FTDF_exitCritical(); |
| } |
| #endif |