Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of fsl_phy_mcr20a by
MPM.c
00001 /*! 00002 * Copyright (c) 2015, Freescale Semiconductor, Inc. 00003 * All rights reserved. 00004 * 00005 * \file MPM.c 00006 * This is the source file for the Multiple PAN Manager. 00007 * 00008 * Redistribution and use in source and binary forms, with or without modification, 00009 * are permitted provided that the following conditions are met: 00010 * 00011 * o Redistributions of source code must retain the above copyright notice, this list 00012 * of conditions and the following disclaimer. 00013 * 00014 * o Redistributions in binary form must reproduce the above copyright notice, this 00015 * list of conditions and the following disclaimer in the documentation and/or 00016 * other materials provided with the distribution. 00017 * 00018 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its 00019 * contributors may be used to endorse or promote products derived from this 00020 * software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00023 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00024 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00025 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00026 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00027 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00029 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 */ 00033 00034 /************************************************************************************ 00035 ************************************************************************************* 00036 * Include 00037 ************************************************************************************* 00038 ************************************************************************************/ 00039 00040 #include "EmbeddedTypes.h " 00041 #include "MpmInterface.h " 00042 #include "Phy.h " 00043 00044 #if 0 00045 #include "FunctionLib.h " 00046 #include "MemManager.h " 00047 #include "Panic.h" 00048 #endif 00049 00050 #if gMpmIncluded_d 00051 00052 /************************************************************************************ 00053 ************************************************************************************* 00054 * Public macros 00055 ************************************************************************************* 00056 ************************************************************************************/ 00057 00058 /************************************************************************************ 00059 ************************************************************************************* 00060 * Public type definitions 00061 ************************************************************************************* 00062 ************************************************************************************/ 00063 00064 /************************************************************************************ 00065 ************************************************************************************* 00066 * Private memory declarations 00067 ************************************************************************************* 00068 ************************************************************************************/ 00069 uint8_t mRegisteredPANs; 00070 bool_t mMpmExclusiveAccess; 00071 panInfo_t mPanInfo[gMpmMaxPANs_c]; 00072 panInfo_t *pActivePANs[gMpmPhyPanRegSets_c]; 00073 00074 /************************************************************************************ 00075 ************************************************************************************* 00076 * Private functions prototypes 00077 ************************************************************************************* 00078 ************************************************************************************/ 00079 static void MPM_SetPanSettingsInPhy( uint8_t panIndex ); 00080 static uint8_t MPM_AllocateResource( bool_t force, uint8_t panIdx ); 00081 00082 /************************************************************************************ 00083 ************************************************************************************* 00084 * Public functions 00085 ************************************************************************************* 00086 ************************************************************************************/ 00087 00088 /*! ********************************************************************************* 00089 * \brief This function determines the instance of the MAC associated with a PHY regSet 00090 * 00091 * \param[in] regSet The PHY registry set 00092 * 00093 * \return The instance of the MAC associated with a PHY registry set. 00094 * 00095 ********************************************************************************** */ 00096 uint32_t MPM_GetMacInstanceFromRegSet(uint32_t regSet) 00097 { 00098 if( pActivePANs[regSet] ) 00099 return pActivePANs[regSet]->macInstance; 00100 00101 return 0; 00102 } 00103 00104 /*! ********************************************************************************* 00105 * \brief This function determines the PHY regSet for the specified panIndex 00106 * 00107 * \param[in] panIdx The index in mPanInfo[] table 00108 * 00109 * \return The PHY registry set. 00110 * 00111 ********************************************************************************** */ 00112 uint32_t MPM_GetRegSet( uint8_t panIdx ) 00113 { 00114 return mPanInfo[panIdx].phyRegSet; 00115 } 00116 00117 /*! ********************************************************************************* 00118 * \brief This function determines the PHY regSet for the specified panIndex 00119 * 00120 * \param[in] pibId The id of the PHY PIB 00121 * \param[in] pValue The value of the PHY PIB 00122 * \param[in] panIdx The index in mPanInfo[] table 00123 * 00124 * \return The status of the operation. 00125 * 00126 ********************************************************************************** */ 00127 phyStatus_t MPM_SetPIB(phyPibId_t pibId, void* pValue, uint8_t panIdx) 00128 { 00129 switch(pibId) 00130 { 00131 #if gMpmUseDifferentTxPwrLevel_c 00132 case gPhyPibTransmitPower_c: 00133 if( (*(uint8_t*)pValue < 3) || (*(uint8_t*)pValue > 31) ) 00134 { 00135 return gPhyInvalidParameter_c; 00136 } 00137 mPanInfo[panIdx].pwrLevel = *(uint8_t*)pValue; 00138 break; 00139 #endif 00140 #if (gMpmMaxPANs_c > gMpmPhyPanRegSets_c) 00141 case gPhyPibCurrentChannel_c: 00142 if( (*(uint8_t*)pValue < 11) || (*(uint8_t*)pValue > 26) ) 00143 { 00144 return gPhyInvalidParameter_c; 00145 } 00146 mPanInfo[panIdx].channel = *(uint8_t*)pValue; 00147 break; 00148 case gPhyPibLongAddress_c: 00149 mPanInfo[panIdx].longAddr = *(uint64_t*)pValue; 00150 break; 00151 case gPhyPibShortAddress_c: 00152 mPanInfo[panIdx].shortAddr = *(uint16_t*)pValue; 00153 break; 00154 case gPhyPibPanId_c: 00155 mPanInfo[panIdx].panId = *(uint16_t*)pValue; 00156 break; 00157 case gPhyPibPanCoordinator_c: 00158 if( *(bool_t*)pValue ) 00159 mPanInfo[panIdx].flags |= gMpmFlagPanCoord_c; 00160 else 00161 mPanInfo[panIdx].flags &= ~gMpmFlagPanCoord_c; 00162 break; 00163 #endif 00164 case gPhyPibRxOnWhenIdle: 00165 if( *(bool_t*)pValue ) 00166 mPanInfo[panIdx].flags |= gMpmFlagRxOnWhenIdle_c; 00167 else 00168 mPanInfo[panIdx].flags &= ~gMpmFlagRxOnWhenIdle_c; 00169 break; 00170 case gPhyPibPromiscuousMode_c: 00171 if( *(bool_t*)pValue ) 00172 mPanInfo[panIdx].flags |= gMpmFlagPromiscuous_c; 00173 else 00174 mPanInfo[panIdx].flags &= ~gMpmFlagPromiscuous_c; 00175 break; 00176 default: 00177 return gPhyUnsupportedAttribute_c; 00178 } 00179 00180 return gPhySuccess_c; 00181 } 00182 00183 phyStatus_t MPM_GetPIB(phyPibId_t pibId, void *pValue, uint8_t panIdx) 00184 { 00185 switch(pibId) 00186 { 00187 #if gMpmUseDifferentTxPwrLevel_c 00188 case gPhyPibTransmitPower_c: 00189 *(uint8_t*)pValue = mPanInfo[panIdx].pwrLevel; 00190 break; 00191 #endif 00192 #if (gMpmMaxPANs_c > gMpmPhyPanRegSets_c) 00193 case gPhyPibCurrentChannel_c: 00194 *(uint8_t*)pValue = mPanInfo[panIdx].channel; 00195 break; 00196 case gPhyPibLongAddress_c: 00197 *(uint64_t*)pValue = mPanInfo[panIdx].longAddr; 00198 break; 00199 case gPhyPibShortAddress_c: 00200 *(uint16_t*)pValue = mPanInfo[panIdx].shortAddr; 00201 break; 00202 case gPhyPibPanId_c: 00203 *(uint16_t*)pValue = mPanInfo[panIdx].panId; 00204 break; 00205 case gPhyPibPanCoordinator_c: 00206 *(uint8_t*)pValue = !!(mPanInfo[panIdx].flags & gMpmFlagPanCoord_c); 00207 break; 00208 #endif 00209 case gPhyPibRxOnWhenIdle: 00210 *(uint8_t*)pValue = !!(mPanInfo[panIdx].flags & gMpmFlagRxOnWhenIdle_c); 00211 break; 00212 case gPhyPibPromiscuousMode_c: 00213 *(uint8_t*)pValue = !!(mPanInfo[panIdx].flags & gMpmFlagPromiscuous_c); 00214 break; 00215 default: 00216 return gPhyUnsupportedAttribute_c; 00217 } 00218 00219 return gPhySuccess_c; 00220 } 00221 00222 00223 /*! ********************************************************************************* 00224 * \brief This function initializes the MPM module. 00225 * 00226 * \param[in] None. 00227 * 00228 * \return None 00229 * 00230 ********************************************************************************** */ 00231 void MPM_Init( void ) 00232 { 00233 uint32_t i; 00234 00235 mRegisteredPANs = 0; 00236 mMpmExclusiveAccess = FALSE; 00237 FLib_MemSet( mPanInfo, 0x00, sizeof(mPanInfo) ); 00238 FLib_MemSet( pActivePANs, 0x00, sizeof(pActivePANs) ); 00239 00240 for(i=0; i<gMpmMaxPANs_c; i++) 00241 mPanInfo[i].phyRegSet = gMpmInvalidRegSet_c; 00242 00243 PhyPpSetDualPanDwell( ((mDefaultDualPanDwellPrescaller_c << mDualPanDwellPrescallerShift_c) & mDualPanDwellPrescallerMask_c) | 00244 ((mDefaultDualPanDwellTime_c << mDualPanDwellTimeShift_c ) & mDualPanDwellTimeMask_c) ); 00245 } 00246 00247 /*! ********************************************************************************* 00248 * \brief This function prepare the Radio for a TX/CCA/ED operation 00249 * 00250 * \param[in] macInstance The instance of the MAC 00251 * 00252 * \return The status of the Operation 00253 * 00254 ********************************************************************************** */ 00255 phyStatus_t MPM_PrepareForTx( instanceId_t macInstance ) 00256 { 00257 uint8_t panIdx = MPM_GetPanIndex(macInstance); 00258 00259 if( TRUE == mMpmExclusiveAccess && mPanInfo[panIdx].locked <= 0 ) 00260 return gPhyChannelBusy_c; 00261 00262 /* Allocate HW Resources if necessary */ 00263 if( mPanInfo[panIdx].phyRegSet == gMpmInvalidRegSet_c ) 00264 { 00265 if( gMpmInvalidRegSet_c == MPM_AllocateResource( TRUE, panIdx ) ) 00266 return gPhyChannelBusy_c; 00267 00268 MPM_SetPanSettingsInPhy( panIdx ); 00269 } 00270 00271 /* Disable DualPan Auto Mode, and select the Active PAN */ 00272 PhyPpSetDualPanAuto( FALSE ); 00273 PhyPpSetDualPanActiveNwk( mPanInfo[panIdx].phyRegSet ); 00274 return gPhySuccess_c; 00275 } 00276 00277 /*! ********************************************************************************* 00278 * \brief This function checks if a PAN has the RxOnWhenIdle PIB set. 00279 * If an Rx needs to be started, it makes the propper settings in PHY. 00280 * 00281 * \param[in] None. 00282 * 00283 * \return phyStatus 00284 * 00285 ********************************************************************************** */ 00286 phyStatus_t MPM_PrepareForRx( instanceId_t macInstance ) 00287 { 00288 uint32_t i, count = 0; 00289 uint32_t activePan; 00290 00291 if( gInvalidInstanceId_c != macInstance ) //Rx 00292 { 00293 i = MPM_GetPanIndex(macInstance); 00294 00295 if( !mMpmExclusiveAccess || mPanInfo[i].locked ) 00296 { 00297 /* Allocate HW Resources if necessary */ 00298 if( mPanInfo[i].phyRegSet == gMpmInvalidRegSet_c ) 00299 { 00300 if( gMpmInvalidRegSet_c == MPM_AllocateResource( TRUE, i ) ) 00301 return gPhyChannelBusy_c; 00302 00303 MPM_SetPanSettingsInPhy( i ); 00304 } 00305 00306 count++; 00307 activePan = mPanInfo[i].phyRegSet; 00308 } 00309 } 00310 else //RxOnWhenIdle 00311 { 00312 for( i=0; i<gMpmPhyPanRegSets_c; i++) 00313 { 00314 if( (NULL != pActivePANs[i]) && 00315 (pActivePANs[i]->flags & gMpmFlagRxOnWhenIdle_c) && 00316 ( !mMpmExclusiveAccess || pActivePANs[i]->locked ) ) 00317 { 00318 activePan = i; 00319 count++; 00320 } 00321 } 00322 } 00323 00324 if( !count ) 00325 return gPhyChannelBusy_c; 00326 00327 /* Set the Active PAN and DualPan Auto mode if needed*/ 00328 PhyPpSetDualPanActiveNwk( activePan ); 00329 PhyPpSetDualPanAuto( count > 1 ); 00330 return gPhySuccess_c; 00331 } 00332 00333 /*! ********************************************************************************* 00334 * \brief This function returns the PAN index for a MAC instance 00335 * 00336 * \param[in] macInstance The instance of the MAC 00337 * 00338 * \return The PAN index or -1 if it was not found 00339 * 00340 ********************************************************************************** */ 00341 int32_t MPM_GetPanIndex( instanceId_t macInstance ) 00342 { 00343 uint32_t i; 00344 00345 /* Get PAN Index for the macInstance */ 00346 for( i=0; i<mRegisteredPANs; i++ ) 00347 { 00348 if( mPanInfo[i].macInstance == macInstance ) 00349 return i; 00350 } 00351 00352 /* The instance of the MAC is not registered! 00353 * Register the current MAC instance if there is enough space. 00354 */ 00355 if( mRegisteredPANs < gMpmMaxPANs_c ) 00356 { 00357 mPanInfo[mRegisteredPANs].macInstance = macInstance; 00358 00359 /* Try to allocate HW resource */ 00360 mPanInfo[mRegisteredPANs].phyRegSet = MPM_AllocateResource( FALSE, i ); 00361 mRegisteredPANs++; 00362 } 00363 else 00364 { 00365 i = -1; 00366 } 00367 00368 return i; 00369 } 00370 00371 00372 /*! ********************************************************************************* 00373 * \brief This function configures the MPM module 00374 * 00375 * \param[in] pCfg pointer to a configuration structure 00376 * 00377 * \remarks 00378 * The Dual PAN dwell time prescaller values: 0-3 00379 * The Dual PAN dwell time values 0-63. 00380 * The (dwellTime+1) represents multiples of the prescaller time base. 00381 * 00382 ********************************************************************************** */ 00383 void MPM_SetConfig( mpmConfig_t *pCfg ) 00384 { 00385 PhyPpSetDualPanAuto ( FALSE ); 00386 PhyPpSetDualPanDwell( pCfg->dwellTime ); 00387 MPM_AllocateResource( TRUE, MPM_GetPanIndex(pCfg->activeMAC) ); 00388 PhyPpSetDualPanAuto ( pCfg->autoMode ); 00389 if( PhyIsIdleRx(0) ) 00390 { 00391 PhyPlmeForceTrxOffRequest(); 00392 Radio_Phy_TimeRxTimeoutIndication(0); 00393 } 00394 } 00395 00396 /*! ********************************************************************************* 00397 * \brief This function returns the MPM configuration 00398 * 00399 * \param[in] pCfg pointer to a configuration structure 00400 * 00401 * \return None. 00402 * 00403 ********************************************************************************** */ 00404 void MPM_GetConfig( mpmConfig_t *pCfg ) 00405 { 00406 pCfg->dwellTime = PhyPpGetDualPanDwell(); 00407 pCfg->activeMAC = MPM_GetMacInstanceFromRegSet( PhyPpGetDualPanActiveNwk() ); 00408 pCfg->autoMode = PhyPpGetDualPanAuto(); 00409 } 00410 #endif /* #if gMpmIncluded_d */ 00411 00412 /*! ********************************************************************************* 00413 * \brief This function Acquires a PAN for exclusive access. 00414 * 00415 * \param[in] macInstance The instance of the MAC 00416 * 00417 * \return The status of the operation 00418 * 00419 ********************************************************************************** */ 00420 phyStatus_t MPM_AcquirePAN( instanceId_t macInstance ) 00421 { 00422 #if gMpmIncluded_d 00423 int32_t panIndex = MPM_GetPanIndex(macInstance); 00424 00425 /* Check if another PAN is acquired */ 00426 if( TRUE == mMpmExclusiveAccess && 00427 mPanInfo[panIndex].locked <= 0 ) 00428 { 00429 return gPhyBusy_c; 00430 } 00431 00432 if( mPanInfo[panIndex].locked == 0 ) 00433 { 00434 mMpmExclusiveAccess = TRUE; 00435 if( PhyIsIdleRx(0) ) 00436 { 00437 PhyPlmeForceTrxOffRequest(); 00438 Radio_Phy_TimeRxTimeoutIndication(0); 00439 } 00440 } 00441 00442 mPanInfo[panIndex].locked++; 00443 #endif 00444 return gPhySuccess_c; 00445 } 00446 00447 /*! ********************************************************************************* 00448 * \brief This function Releases a PAN that was Acquired 00449 * 00450 * \param[in] macInstance The instance of the MAC 00451 * 00452 * \return The status of the operation 00453 * 00454 ********************************************************************************** */ 00455 phyStatus_t MPM_ReleasePAN( instanceId_t macInstance ) 00456 { 00457 #if gMpmIncluded_d 00458 uint8_t panIndex = MPM_GetPanIndex(macInstance); 00459 00460 mPanInfo[panIndex].locked--; 00461 if( mPanInfo[panIndex].locked == 0 ) 00462 { 00463 mMpmExclusiveAccess = FALSE; 00464 if( PhyIsIdleRx(0) ) 00465 { 00466 PhyPlmeForceTrxOffRequest(); 00467 Radio_Phy_TimeRxTimeoutIndication(0); 00468 } 00469 } 00470 #endif 00471 return gPhySuccess_c; 00472 } 00473 00474 /************************************************************************************ 00475 ************************************************************************************* 00476 * Private functions 00477 ************************************************************************************* 00478 ************************************************************************************/ 00479 #if gMpmIncluded_d 00480 /*! ********************************************************************************* 00481 * \brief This function alocates a registry set to a PAN. 00482 * 00483 * \param[in] force If this parameter is TRUE, then another PAN can be preempted. 00484 * \param[in] panIdx The index into the MPM database 00485 * 00486 * \return The register set allocated for the specified PAN. 00487 * 00488 ********************************************************************************** */ 00489 static uint8_t MPM_AllocateResource( bool_t force, uint8_t panIdx ) 00490 { 00491 uint32_t i, regSet = gMpmInvalidRegSet_c; 00492 00493 if( mPanInfo[panIdx].phyRegSet != gMpmInvalidRegSet_c ) 00494 return mPanInfo[panIdx].phyRegSet; 00495 00496 for( i=0; i<gMpmPhyPanRegSets_c; i++ ) 00497 { 00498 if( NULL == pActivePANs[i] ) 00499 { 00500 regSet = i; 00501 break; 00502 } 00503 else if( (force) && 00504 (pActivePANs[i]->flags == 0) && 00505 (pActivePANs[i]->locked <= 0) ) 00506 { 00507 regSet = i; 00508 } 00509 } 00510 00511 if( regSet != gMpmInvalidRegSet_c ) 00512 { 00513 if( NULL != pActivePANs[regSet] ) 00514 { 00515 pActivePANs[regSet]->phyRegSet = gMpmInvalidRegSet_c; 00516 } 00517 00518 pActivePANs[regSet] = &mPanInfo[panIdx]; 00519 pActivePANs[regSet]->phyRegSet = regSet; 00520 } 00521 00522 return regSet; 00523 } 00524 00525 /*! ********************************************************************************* 00526 * \brief This function will store PAN settings in PHY. 00527 * 00528 * \param[in] panIdx The index into the MPM database 00529 * 00530 * \return None. 00531 * 00532 * \remarks Function assumes that the PAN is active! 00533 * 00534 ********************************************************************************** */ 00535 static void MPM_SetPanSettingsInPhy( uint8_t panIndex ) 00536 { 00537 panInfo_t *pPAN = &mPanInfo[panIndex]; 00538 00539 #if gMpmUseDifferentTxPwrLevel_c 00540 PhyPlmeSetPIBRequest(gPhyPibTransmitPower_c, pPAN->pwrLevel, pPAN->phyRegSet, 0 ); 00541 #endif 00542 00543 #if (gMpmMaxPANs_c > gMpmPhyPanRegSets_c) 00544 PhyPlmeSetPIBRequest(gPhyPibPromiscuousMode_c, !!(pPAN->flags & gMpmFlagPromiscuous_c), pPAN->phyRegSet, 0 ); 00545 PhyPlmeSetPIBRequest(gPhyPibRxOnWhenIdle, !!(pPAN->flags & gMpmFlagRxOnWhenIdle_c), pPAN->phyRegSet, 0 ); 00546 PhyPlmeSetPIBRequest(gPhyPibPanCoordinator_c, !!(pPAN->flags & gMpmFlagPanCoord_c), pPAN->phyRegSet, 0 ); 00547 PhyPlmeSetPIBRequest(gPhyPibPanId_c, pPAN->panId, pPAN->phyRegSet, 0 ); 00548 PhyPlmeSetPIBRequest(gPhyPibShortAddress_c, pPAN->shortAddr, pPAN->phyRegSet, 0 ); 00549 PhyPlmeSetPIBRequest(gPhyPibLongAddress_c, pPAN->longAddr, pPAN->phyRegSet, 0 ); 00550 PhyPlmeSetPIBRequest(gPhyPibCurrentChannel_c, pPAN->channel, pPAN->phyRegSet, 0 ); 00551 #else 00552 (void)pPAN; 00553 #endif 00554 } 00555 #endif /* gMpmIncluded_d */
Generated on Fri Jul 15 2022 21:41:17 by
