1 /*! ********************************************************************************* 2 * Copyright (c) 2015, Freescale Semiconductor, Inc. 3 * Copyright 2018, 2023-2025 NXP 4 * All rights reserved. 5 * 6 * \file 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 ********************************************************************************** */ 10 11 #ifndef __PHY_H__ 12 #define __PHY_H__ 13 14 /*! ********************************************************************************* 15 ************************************************************************************* 16 * Include 17 ************************************************************************************* 18 ********************************************************************************** */ 19 #include "EmbeddedTypes.h" 20 #include "PhyInterface.h" 21 #include "PhyTime.h" 22 #include "fsl_os_abstraction.h" 23 #include "PhyPlatform.h" 24 25 26 /*! ********************************************************************************* 27 ************************************************************************************* 28 * Private macros 29 ************************************************************************************* 30 ********************************************************************************** */ 31 #define mFrameCtrlLo_d (0) 32 #define mFrameCtrlHi_d (1) 33 #define mAddressingFields_d (3) 34 35 #define mShortAddr_d (2) 36 #define mExtAddr_d (3) 37 #define mNoAddr_d (0) 38 #define mPanIdCompression_d (1 << 6) 39 #define mDstAddrModeMask_d (0x0C) 40 #define mDstAddrModeShift_d (2) 41 #define mSrcAddrModeMask_d (0xC0) 42 #define mSrcAddrModeShift_d (6) 43 44 45 46 /*! ********************************************************************************* 47 ************************************************************************************* 48 * Public macros 49 ************************************************************************************* 50 ********************************************************************************** */ 51 52 #ifdef __cplusplus 53 extern "C" { 54 #endif 55 56 57 #undef CTX_NO 58 59 #ifdef CTX_SCHED 60 #define CTX_NO 2 61 #else 62 #define CTX_NO 1 63 #endif 64 65 66 #ifdef CTX_SCHED 67 68 typedef enum 69 { 70 NONE_OP = 0, 71 RX_OP = 1, 72 CCA_OP = 2, 73 TX_OP = 3 74 } proto_op; 75 76 typedef enum 77 { 78 E_SCHED_PROTO_OFF, /* disabled */ 79 E_SCHED_PROTO_INACTIVE, /* waiting for radio ownership */ 80 E_SCHED_PROTO_PAUSING, /* interrupted by switch timer */ 81 E_SCHED_PROTO_ACTIVE /* current radio owner */ 82 } proto_state; 83 84 #endif /* CTX_SCHED */ 85 86 87 #define PHY_TEN_SYMBOLS_US 160 88 #define PHY_SYMBOLS_US 16 89 90 #define INV_IDX ((uint32_t)(-1)) 91 92 93 enum 94 { 95 PHY_IMM_ACK_LENGTH = 5, /* Size of a Imm-ACK in bytes */ 96 PHY_ENH_ACK_LENGTH = 50, /* Size of a Enh-ACK in bytes */ 97 PHY_IE_HEADER_SIZE = 2, /* Size of IE header in bytes */ 98 PHY_CSL_IE_SIZE = 4, /* Size of CSL IE content in bytes */ 99 PHY_CSL_TOTAL_SIZE = 6, /* Total size of CSL IE in bytes */ 100 PHY_ACK_IE_MAX_SIZE = 16, /* Max length for header IE in ACK */ 101 PHY_LEN_SIZE_BYTES = 1, /* Size of LEN field in bytes */ 102 PHY_ASH_SEC_CTRL_SIZE = 1, /* Size of ASH security control field in bytes */ 103 PHY_ASH_FRAME_CNT_SIZE = 4, /* Size of ASH frame counter field in bytes */ 104 PHY_ASH_KEY_IDX_SIZE = 1, /* Size of key index from ASH key identifier in bytes */ 105 PHY_ASH_TOTAL_SIZE = 6, /* Total size of the ASH using key id mode 1, no frame counter suppression */ 106 PHY_MAC_CMD_ID_SIZE = 1 /* Size of CMD ID in MAC Command packet */ 107 }; 108 109 /*! Structure used to keep IE data for a specific peer */ 110 typedef struct phyIeData_tag 111 { 112 uint8_t ieData[PHY_ACK_IE_MAX_SIZE]; 113 uint8_t extAddr[8]; 114 uint16_t shortAddr; 115 uint32_t ieParam; // MSB: =1 if ieData has valid data including valid Data Length in IE Header Data (first 2 data bytes) 116 // Rest of the bits hold eventual params (IE Specific) 117 } phyIeData_t; 118 119 120 static volatile uint8_t * const RX_PB = (uint8_t *)(TX_PACKET_RAM_BASE + 0x80U); 121 static volatile uint8_t * const TX_PB = (uint8_t *)(TX_PACKET_RAM_BASE); 122 123 #ifndef TX_PB_TRY_CNT 124 #define TX_PB_TRY_CNT 10 125 #endif 126 127 static const uint32_t RX_WTMRK_START = 3; /* frame length + FCF */ 128 129 130 /* XCVR idle power mode */ 131 #define gPhyDefaultIdlePwrMode_c gPhyPwrIdle_c 132 133 /*! ********************************************************************************* 134 ************************************************************************************* 135 * Public type definitions 136 ************************************************************************************* 137 ********************************************************************************** */ 138 /* PHY states */ 139 enum 140 { 141 gIdle_c, 142 gRX_c, 143 gTX_c, 144 gCCA_c, 145 gTR_c, 146 gCCCA_c, 147 }; 148 149 /* ZSM STATE */ 150 enum 151 { 152 g_ZSM_SEQ_IDLE = 0x0, 153 g_ZSM_RX_WU = 0x10, 154 g_ZSM_RX_PRE = 0x14, 155 g_ZSM_RX_PKT = 0x15, 156 g_ZSM_RX2ACK = 0x16, 157 g_ZSM_RX_CYC = 0x17, 158 g_ZSM_RX_PAN1 = 0x1D, 159 g_ZSM_RX_PAN2 = 0x1E, 160 g_ZSM_RX_CCA1 = 0x18, 161 g_ZSM_CCA2_WAIT = 0x19, 162 g_ZSM_RX_CCA2 = 0x1A, 163 g_ZSM_RX_CCCA = 0x1C, 164 g_ZSM_RX2TX = 0x1B, 165 g_ZSM_TX_WU = 0x01, 166 g_ZSM_TX_PKT = 0x05, 167 g_ZSM_TX_ACK = 0x06, 168 g_ZSM_TX_SLOT = 0x07, 169 g_ZSM_TX_WD = 0x08, 170 g_ZSM_TX_PA_OFF = 0x09, 171 g_ZSM_XTRA_CLK1 = 0x0A, 172 g_ZSM_TX2RX = 0x0B, 173 g_ZSM_TSM_WD = 0x1F 174 }; 175 176 /* PHY channel state */ 177 enum 178 { 179 gChannelIdle_c, 180 gChannelBusy_c 181 }; 182 183 /* PANCORDNTR bit in PP */ 184 enum 185 { 186 gMacRole_DeviceOrCoord_c, 187 gMacRole_PanCoord_c 188 }; 189 190 /* Cca types */ 191 enum 192 { 193 gCcaED_c, /* energy detect - CCA bit not active, not to be used for T and CCCA sequences */ 194 gCcaCCA_MODE1_c, /* energy detect - CCA bit ACTIVE */ 195 gCcaCCA_MODE2_c, /* 802.15.4 compliant signal detect - CCA bit ACTIVE */ 196 gCcaCCA_MODE3_c, /* 802.15.4 compliant signal detect and energy detect - CCA bit ACTIVE */ 197 gInvalidCcaType_c /* illegal type */ 198 }; 199 200 enum 201 { 202 gNormalCca_c, 203 gContinuousCca_c 204 }; 205 206 207 208 #ifdef CTX_SCHED 209 210 typedef enum 211 { 212 E_SCHED_NO_POLICY, /* Internal use reserved */ 213 E_SCHED_DUTY_CYCLE, /* Round robin manner with a configured time slice for each protocol */ 214 E_SCHED_LOCKED, /* Locking only one protocol until the policy is changed or timeout */ 215 E_SCHED_PRIORITY, /* Defines a priority for each protocol and scheduler will select the highest priority to run 216 based on pending operations*/ 217 } sched_policy; 218 219 #endif 220 221 typedef enum 222 { 223 ENH_ACK_INVALID, 224 ENH_ACK_RESET, 225 ENH_ACK_READY 226 } enh_ack_state_t; 227 228 #if defined(FFU_DEVICE_LIMIT_VISIBILITY) 229 230 #ifndef N_FILTER_DEVICES 231 #define N_FILTER_DEVICES 6 232 #endif 233 234 /* 235 8-bytes address (long device address / little endian) base type 236 */ 237 typedef uint8_t ieee_64bit_addr_t[8]; 238 239 /* 240 External (64-bit) device address 241 */ 242 typedef ieee_64bit_addr_t ext_addr_t; 243 244 /* 245 Device Filtering Context 246 */ 247 typedef struct 248 { 249 uint8_t nVisibleDevice; 250 ext_addr_t aVisibleExtAddr[N_FILTER_DEVICES]; 251 uint8_t nInvisibleDevice; 252 uint16_t aInvisibleLocalAddr[N_FILTER_DEVICES]; 253 uint16_t aVisibleLocalAddr[N_FILTER_DEVICES]; 254 bool_t bDisableBeaconFrame; 255 } visible_filter_t; 256 #endif 257 258 typedef struct Phy_PhyLocalStruct_tag 259 { 260 instanceId_t id; 261 262 PD_MAC_SapHandler_t PD_MAC_SapHandler; 263 PLME_MAC_SapHandler_t PLME_MAC_SapHandler; 264 265 phyTxParams_t txParams; 266 phyRxParams_t rxParams; 267 phyCcaParams_t ccaParams; 268 269 phyChannelParams_t channelParams; 270 271 volatile uint8_t flags; 272 273 uint8_t mPhyLastRxLQI; 274 int8_t mPhyLastRxRSSI; 275 276 uint8_t trx_buff[gMaxPHYPacketSize_c + PHY_LEN_SIZE_BYTES]; /* trx PBs are 128 bytes */ 277 278 uint32_t phyCslPeriod; 279 uint32_t phyCslSampleTimeUs; 280 281 uint8_t ackIeDataAndHdr[PHY_CSL_IE_SIZE + PHY_IE_HEADER_SIZE]; 282 283 phyIeData_t phyIeDataTable[gPhyIeDataTableSize]; 284 285 bool_t phySecurity; 286 287 uint8_t prevKey[PHY_SEC_KEY_SIZE]; 288 uint8_t currKey[PHY_SEC_KEY_SIZE]; 289 uint8_t nextKey[PHY_SEC_KEY_SIZE]; 290 291 uint8_t keyId; 292 uint32_t frameCounter; 293 uint32_t updateFrameCounter; 294 295 bool_t efp; /* Enhanced FP */ 296 297 phyMessageId_t delayed_msg; /* for postponed operations due to no memory */ 298 299 uint8_t filter_fail; 300 301 enh_ack_state_t enh_ack_state; 302 bool_t neighbourTblEnabled; 303 304 #if defined(FFU_DEVICE_LIMIT_VISIBILITY) 305 visible_filter_t sFilter; 306 #endif 307 308 #ifdef CTX_SCHED 309 proto_state state; 310 proto_op op; /* rx / tx / CCA */ 311 312 bool_t tx_cca_pending; 313 bool_t rx_ongoing; 314 315 pdDataReq_t tx_data_req; 316 317 /* Policy related members */ 318 uint8_t priority; 319 uint32_t slice; 320 uint32_t lock_timeout; 321 uint32_t tstp; /* trx request timestamp */ 322 #endif /* CTX_SCHED */ 323 } Phy_PhyLocalStruct_t; 324 325 #if (WEIGHT_IN_LQI_CALCULATION == 1) 326 typedef struct Phy_nbRssiCtrl_tag 327 { 328 uint8_t wt_snr; 329 uint8_t wt_rssi; 330 uint8_t lqi_bias; 331 uint8_t lqi_rssi_sens; 332 }Phy_nbRssiCtrl_t; 333 #endif 334 335 /*! ********************************************************************************* 336 ************************************************************************************* 337 * Public prototypes 338 ************************************************************************************* 339 ********************************************************************************** */ 340 341 /* PHY Packet Processor */ 342 343 /*! ********************************************************************************* 344 * \brief Initialize the XCVR HW 345 * 346 ********************************************************************************** */ 347 void PhyHwInit(void); 348 349 /*! ********************************************************************************* 350 * \brief Enable/Disable the XCVR promiscuous mode. 351 * In promiscuous mode, all filtering except CRC are disabled 352 * 353 * \param[in] mode TRUE - Promiscuous On 354 * FALSE - Promiscous Off 355 * 356 ********************************************************************************** */ 357 void PhyPpSetPromiscuous(bool_t mode); 358 359 /*! ********************************************************************************* 360 * \brief Enable/Disable the XCVR active promiscuous mode. 361 * In active promiscuous mode, all filtering except CRC are disabled. 362 * Also, the XCVR will send ACK to frames with destination address equal to 363 * the device's address 364 * 365 * \param[in] sate TRUE - Promiscuous On 366 * FALSE - Promiscous Off 367 * 368 ********************************************************************************** */ 369 void PhySetActivePromiscuous(bool_t state); 370 371 /*! ********************************************************************************* 372 * \brief Returns the state of the Active Promiscuous feature 373 * 374 ********************************************************************************** */ 375 bool_t PhyGetActivePromiscuous(void); 376 377 /*! ********************************************************************************* 378 * \brief Set the device's PAN Id 379 * 380 * \param 381 * 382 * \return status 383 * 384 ********************************************************************************** */ 385 phyStatus_t PhyPpSetPanId(uint8_t *pPanId, uint8_t pan); 386 387 /*! ********************************************************************************* 388 * \brief Set the device's Short Address 389 * 390 * \param 391 * 392 * \return status 393 * 394 ********************************************************************************** */ 395 phyStatus_t PhyPpSetShortAddr(uint8_t *pShortAddr, uint8_t pan); 396 397 /*! ********************************************************************************* 398 * \brief Set the device's IEEE Address 399 * 400 * \param 401 * 402 * \return status 403 * 404 ********************************************************************************** */ 405 phyStatus_t PhyPpSetLongAddr(uint8_t *pLongAddr, uint8_t pan); 406 407 /*! ********************************************************************************* 408 * \brief Get the device's IEEE Address 409 * 410 * \param 411 * 412 * \return status 413 * 414 ********************************************************************************** */ 415 phyStatus_t PhyPpGetLongAddr(uint8_t *pLongAddr, uint8_t pan); 416 417 /*! ********************************************************************************* 418 * \brief Set the device's role: Pan coordinator or not 419 * 420 * \param 421 * 422 * \return status 423 * 424 ********************************************************************************** */ 425 phyStatus_t PhyPpSetMacRole(bool_t macRole, uint8_t pan); 426 427 /*! ********************************************************************************* 428 * \brief Get the state of the FP bit sent in last ACK frame 429 * 430 * \return state of FP bit 431 * 432 ********************************************************************************** */ 433 bool_t PhyPpIsTxAckDataPending(void); 434 435 /*! ********************************************************************************* 436 * \brief Get the state of the FP bit of the last received ACK frame 437 * 438 * \return state of FP bit 439 * 440 ********************************************************************************** */ 441 bool_t PhyPpIsRxAckDataPending(void); 442 443 /*! ********************************************************************************* 444 * \brief Set the value of the FP bit for the next ACK frame 445 * 446 * \param[in] FP value of FP bit 447 * 448 ********************************************************************************** */ 449 void PhyPpSetFpManually(bool_t FP); 450 451 /*! ********************************************************************************* 452 * \brief Check if the lasr received packet was a Poll Request 453 * 454 * \return TRUE if the received packet is a Poll Request 455 * 456 ********************************************************************************** */ 457 bool_t PhyPpIsPollIndication(void); 458 459 /*! ********************************************************************************* 460 * \brief Enable/Disable Source Addressing Match feature 461 * 462 * \param[in] state of the SAM feature 463 * 464 ********************************************************************************** */ 465 void PhyPpSetSAMState(instanceId_t instanceId, bool_t state); 466 467 /*! ********************************************************************************* 468 * \brief Add a new entry into the Neighbour table 469 * 470 * \param[in] index The table position 471 * \param[in] checkSum The device hash code 472 * \param[in] instanceId The instance of the PHY 473 * 474 * \return status 475 * 476 ********************************************************************************** */ 477 phyStatus_t PhyPp_AddNeighbour(uint32_t index, uint16_t checkSum, instanceId_t instanceId); 478 479 /*! ********************************************************************************* 480 * \brief Remove an entry from Neighbour table 481 * 482 * \param[in] index The table position 483 * \param[in] instanceId The instance of the PHY 484 * 485 * \return status 486 * 487 ********************************************************************************** */ 488 phyStatus_t PhyPp_RemoveNeighbour(uint32_t index, instanceId_t instanceId); 489 490 /*! ********************************************************************************* 491 * \brief Clear every entry in the Neighbour table 492 * 493 * \param[in] instanceId The instance of the PHY 494 * 495 * \return status 496 * 497 ********************************************************************************** */ 498 phyStatus_t PhyPp_ClearNeighbourTbl(instanceId_t instanceId); 499 /*! ********************************************************************************* 500 * \brief Add a new entry into the HW indirect queue 501 * 502 * \param[in] index The table position 503 * \param[in] checkSum The device hash code 504 * \param[in] instanceId The instance of the PHY 505 * 506 * \return status 507 * 508 ********************************************************************************** */ 509 phyStatus_t PhyPp_IndirectQueueInsert(uint32_t index, uint16_t checkSum, instanceId_t instanceId); 510 511 /*! ********************************************************************************* 512 * \brief Remove an entry from the HW indirect queue 513 * 514 * \param[in] index The table position 515 * \param[in] instanceId The instance of the PHY 516 * 517 * \return status 518 * 519 ********************************************************************************** */ 520 phyStatus_t PhyPp_RemoveFromIndirect(uint32_t index, instanceId_t instanceId); 521 522 /*! ********************************************************************************* 523 * \brief Get the current state of the XCVR 524 * 525 * \return state 526 * 527 ********************************************************************************** */ 528 uint8_t PhyPpGetState(void); 529 530 /*! ********************************************************************************* 531 * \brief Abort the current XCVR sequence 532 * 533 ********************************************************************************** */ 534 void PhyAbort(void); 535 536 bool_t PHY_graceful_idle(); 537 538 /* PHY PLME & DATA primitives */ 539 540 /*! ********************************************************************************* 541 * \brief Start a TX sequence 542 * 543 * \param[in] pTxPacket Pointer to the PD request 544 * \param[in] pRxParams Pointer to the Rx parameters 545 * \param[in] pTxParams Pointer to the Tx parameters 546 * 547 * \return status 548 * 549 ********************************************************************************** */ 550 phyStatus_t PhyPdDataRequest(Phy_PhyLocalStruct_t *ctx); 551 552 /*! ********************************************************************************* 553 * \brief Start an RX sequence 554 * 555 * \param[in] phyRxMode Slotted/Unslotted 556 * \param[in] pRxParams Pointer to the Rx parameters 557 * 558 * \return status 559 * 560 ********************************************************************************** */ 561 phyStatus_t PhyPlmeRxRequest(Phy_PhyLocalStruct_t *ctx); 562 563 /*! ********************************************************************************* 564 * \brief Start a immed RX sequence 565 * 566 * \param[in] pRxParams Pointer to the Rx parameters 567 * 568 * \return status 569 * 570 ********************************************************************************** */ 571 phyStatus_t PhyPlmeTimmedRxRequest(phyRxParams_t *pRxParams); 572 573 /*! ********************************************************************************* 574 * \brief Start a CCA or ED sequence 575 * 576 * \param[in] ccaParam type of CCA 577 * \param[in] cccaMode continuous or single operation 578 * 579 * \return status 580 * 581 ********************************************************************************** */ 582 phyStatus_t PhyPlmeCcaEdRequest(Phy_PhyLocalStruct_t *ctx); 583 584 /*! ********************************************************************************* 585 * \brief Set the current 802.15.4 channel 586 * 587 * \param[in] channel number [11-26] 588 * \param[in] pan index of the PAN 589 * 590 * \return status 591 * 592 ********************************************************************************** */ 593 phyStatus_t PhyPlmeSetCurrentChannelRequest(uint8_t channel, uint8_t pan); 594 595 /*! ********************************************************************************* 596 * \brief Get the current 802.15.4 channel 597 * 598 * \param[in] pan index of the PAN 599 * 600 * \return status 601 * 602 ********************************************************************************** */ 603 uint8_t PhyPlmeGetCurrentChannelRequest(uint8_t pan); 604 605 /*! ********************************************************************************* 606 * \brief Set the TX power level 607 * 608 * \param[in] pwrStep the Tx power level 609 * 610 * \return status 611 * 612 ********************************************************************************** */ 613 phyStatus_t PhyPlmeSetPwrLevelRequest(int8_t pwrStep); 614 615 /*! ********************************************************************************* 616 * \brief Get the TX power level 617 * 618 * \return current power level 619 * 620 ********************************************************************************** */ 621 uint8_t PhyPlmeGetPwrLevelRequest(void); 622 623 /*! ********************************************************************************* 624 * \brief Set a PHY PIB 625 * 626 * \param[in] pibId The Id of the PIB 627 * \param[in] pibValue The value of the PIB 628 * \param[in] phyRegistrySet The index of the PAN 629 * \param[in] instanceId The instance of the PHY 630 * 631 * \return status 632 * 633 ********************************************************************************** */ 634 phyStatus_t PhyPlmeSetPIBRequest(phyPibId_t pibId, uint64_t pibValue, instanceId_t instanceId); 635 636 /*! ********************************************************************************* 637 * \brief Get a PHY PIB 638 * 639 * \param[in] pibId The Id of the PIB 640 * \param[in] pibValue Pointer to a location where the value will be stored 641 * \param[in] phyRegistrySet The index of the PAN 642 * \param[in] instanceId The instance of the PHY 643 * 644 * \return status 645 * 646 ********************************************************************************** */ 647 phyStatus_t PhyPlmeGetPIBRequest(phyPibId_t pibId, uint8_t *pibValue, instanceId_t instanceId); 648 649 /*! ********************************************************************************* 650 * \brief Set the value of the CCA Threshold 651 * 652 * \param[in] ccaThreshold the threshold value 653 * 654 * \return status 655 * 656 ********************************************************************************** */ 657 658 phyStatus_t PhyPpSetCcaThreshold(uint8_t ccaThreshold); 659 660 /* PHY Time */ 661 /*! ********************************************************************************* 662 * \brief Get the absolute end time of the next sequence 663 * 664 * \return the sequence timeout 665 * 666 ********************************************************************************** */ 667 phyTime_t PhyTimeGetEventTimeout(void); 668 669 /*! ********************************************************************************* 670 * \brief Read the XCVR timer 671 * 672 * \return value of the timer 673 * 674 ********************************************************************************** */ 675 phyTime_t PhyTime_ReadClock(); 676 677 /* PHY ISR */ 678 679 /*! ********************************************************************************* 680 * \brief This function forces the PHY IRQ to be triggered to run the ISR 681 * 682 ********************************************************************************** */ 683 void PHY_ForceIrqPending(void); 684 685 /*! ********************************************************************************* 686 * \brief This is the XCVR ISR 687 * 688 ********************************************************************************** */ 689 void PHY_InterruptHandler(); 690 691 /*! ********************************************************************************* 692 * \brief Set the state of the Dual PAN automatic mode 693 * 694 * \param[in] mode of the Dual PAN automatic mode 695 * 696 ********************************************************************************** */ 697 void PhyPpSetDualPanAuto(bool_t mode); 698 699 /*! ********************************************************************************* 700 * \brief Get the state of the Dual PAN automatic mode 701 * 702 * \return the state of the Dual PAN automatic mode 703 * 704 ********************************************************************************** */ 705 bool_t PhyPpGetDualPanAuto(void); 706 707 /*! ********************************************************************************* 708 * \brief Set the Dual PAN Dwell switch time 709 * 710 ********************************************************************************** */ 711 void PhyPpSetDualPanDwell(uint8_t dwell); 712 713 /*! ********************************************************************************* 714 * \brief Get the Dual PAN Dwell switch time 715 * 716 * \return dwell time 717 * 718 ********************************************************************************** */ 719 uint8_t PhyPpGetDualPanDwell(void); 720 721 /*! ********************************************************************************* 722 * \brief Get the remaining time until a channel switch will occure 723 * 724 * \return remaining time until PAN switch wil occur 725 * 726 ********************************************************************************** */ 727 uint8_t PhyPpGetDualPanRemain(void); 728 729 /*! ********************************************************************************* 730 * \brief Set the active PAN 731 * 732 * \param[in] the index of the PAN 733 * 734 ********************************************************************************** */ 735 void PhyPpSetDualPanActiveNwk(uint8_t nwk); 736 737 /*! ********************************************************************************* 738 * \brief Returns the current NWK on which the PHY is operating 739 * 740 * \return the index of the active PAN 741 * 742 ********************************************************************************** */ 743 uint8_t PhyPpGetDualPanActiveNwk(void); 744 745 /*! ********************************************************************************* 746 * \brief Return the PAN on which the packet was received (can be receiced on both PANs) 747 * 748 * \return the PAN index 749 * 750 ********************************************************************************** */ 751 uint8_t PhyPpGetPanOfRxPacket(void); 752 753 /*! ********************************************************************************* 754 * \brief Return the LQI value for the last received packet 755 * 756 * \return LQI 757 * 758 ********************************************************************************** */ 759 uint8_t PhyGetLastRxLqiValue(instanceId_t id); 760 761 /*! ********************************************************************************* 762 * \brief Returns the RSSI value for the last received packet 763 * 764 * \return RSSI 765 * 766 ********************************************************************************** */ 767 uint8_t PhyGetLastRxRssiValue(instanceId_t id); 768 769 /*! ********************************************************************************* 770 * \brief This function converts the LQI reported by the PHY into an signed RSSI value 771 * 772 * \param[in] LQI the LQI reported by the PHY 773 * 774 * \return the RSSI value in dbm 775 * 776 ********************************************************************************** */ 777 int8_t PhyConvertLQIToRSSI(uint8_t lqi); 778 779 /*! ********************************************************************************* 780 * \brief Enable the FAD function (FAD_EN bit) 781 * 782 * \param[in] state , the state of the FAD feature 783 * 784 * \return gPhySuccess 785 * 786 ********************************************************************************** */ 787 uint8_t PhyPlmeSetFADStateRequest(bool_t state); 788 789 /*! ********************************************************************************* 790 * \brief Correlator threshold at which the FAD will select the antenna 791 * 792 * \return gPhySuccess 793 * 794 ********************************************************************************** */ 795 uint8_t PhyPlmeSetFADThresholdRequest(uint8_t FADThreshold); 796 797 /*! ********************************************************************************* 798 * \brief Enable the ANT pads 799 * 800 * \param[in] antAB_on - 801 * \param[in] rxtxSwitch_on - 802 * 803 * \return gPhySuccess 804 * 805 ********************************************************************************** */ 806 uint8_t PhyPlmeSetANTPadStateRequest(bool_t antAB_on, bool_t rxtxSwitch_on); 807 808 /*! ********************************************************************************* 809 * \brief Invert the logic of the ANT pads 810 * 811 * \param[in] invAntA - invert the ANT_A pad 812 * \param[in] invAntB - invert the ANT_A pad 813 * \param[in] invTx - invert the ANT_TX pad 814 * \param[in] invRx - invert the ANT_RX pad 815 * 816 * \return gPhySuccess 817 * 818 ********************************************************************************** */ 819 uint8_t PhyPlmeSetANTPadInvertedRequest(bool_t invAntA, bool_t invAntB, bool_t invTx, bool_t invRx); 820 821 /*! ********************************************************************************* 822 * \brief Set FAD Antenna start when FAD_EN = 1 or antenna selected when FAD_EN=0 823 * 824 * \return gPhySuccess 825 * 826 ********************************************************************************** */ 827 uint8_t PhyPlmeSetANTXStateRequest(bool_t state); 828 829 /*! ********************************************************************************* 830 * \brief Antenna selected in FAD of non-FAD mode 831 * 832 * \return Chosen antenna by the FAD (FAD_EN = 1) or copy of ANTX_IN 833 * 834 ********************************************************************************** */ 835 uint8_t PhyPlmeGetANTXStateRequest(void); 836 837 /*! ********************************************************************************* 838 * \brief This function will return the CCA Type 839 * 840 * \return phyCCAType_t : 841 * gPhyEnergyDetectMode_c = 0x00, 842 * gPhyCCAMode1_c = 0x01, Energy above a threshold 843 * gPhyCCAMode2_c = 0x02, Carrier sense only 844 * gPhyCCAMode3_c = 0x03, CCA mode 1 + CCA mode 2 845 *\ 846 ********************************************************************************** */ 847 phyCCAType_t PhyPlmeGetCCATypeRequest(void); 848 849 /*! ********************************************************************************* 850 * \brief Choose CCA3 Mode: 1 - CCA1 AND CCA2, 851 * 0 - CCA1 OR CCA2 852 * 853 * \return gPhySuccess 854 * 855 ********************************************************************************** */ 856 phyStatus_t PhyPlmeSetCCA3ModeRequest(phyCCA3Mode_t cca3Mode); 857 858 /*! ********************************************************************************* 859 * \brief Returns the CCA3 Mode value 860 * 861 * \return phyCCA3Mode_t. 1 - CCA1 AND CCA2, 0 - CCA1 OR CCA2 862 * 863 ********************************************************************************** */ 864 phyCCA3Mode_t PhyPlmeGetCCA3ModeRequest(void); 865 866 /*! ********************************************************************************* 867 * \brief Returns the RSSI level value, refreshed every 125us 868 * 869 * \param[in] instanceId - the instance of the PHY 870 * 871 * \return RSSI level [dbm] 872 * 873 ********************************************************************************** */ 874 uint8_t PhyPlmeGetRSSILevelRequest(instanceId_t instanceId); 875 876 int8_t PHY_handle_get_RSSI(Phy_PhyLocalStruct_t *ctx); 877 878 /*! ********************************************************************************* 879 * \brief This function will return the promiscuous state 880 * 881 * \return bool_t 882 * 883 ********************************************************************************** */ 884 bool_t PhyPlmeGetPromiscuousRequest(void); 885 886 /*! ********************************************************************************* 887 * \brief Informs the PHY if it should start an RX when entering IDLE or not 888 * 889 * \param[in] state - if TRUE the XCVR will start an Rx when Idle 890 * \param[in] instanceId - the instance of the PHY 891 * 892 ********************************************************************************** */ 893 void PhyPlmeSetRxOnWhenIdle(bool_t state, instanceId_t instanceId); 894 895 /*! ********************************************************************************* 896 * \brief Set the start time and end time for an XCVR sequence 897 * 898 * \param[in] startTime - absolute start time in symbols 899 * \param[in] seqDuration - sequence duration in symbols 900 * 901 ********************************************************************************** */ 902 void Phy_SetSequenceTiming(phyTime_t *startTime, uint32_t seqDuration, uint32_t overhead); 903 904 /*! ********************************************************************************* 905 * \brief Scales energy level to 0-255 906 * 907 * \param[in] energyLevel the energy level reported by HW 908 * 909 * \return uint8_t the energy level scaled in 0x00-0xFF 910 * 911 ********************************************************************************** */ 912 uint8_t Phy_GetEnergyLevel(uint8_t energyLevel); 913 914 /*! ********************************************************************************* 915 * \brief Disable the XCVR interrupts 916 * 917 ********************************************************************************** */ 918 void ProtectFromXcvrInterrupt(void); 919 920 /*! ********************************************************************************* 921 * \brief Enable the XCVR interrupts 922 * 923 ********************************************************************************** */ 924 void UnprotectFromXcvrInterrupt(void); 925 926 #if (AUTO_ACK_DISABLE_SUPPORT == 1) 927 /*! ********************************************************************************* 928 * \brief Enable the 802.15.4 radio Auto Acknowledge 929 * 930 ********************************************************************************** */ 931 void PhyEnableAutoAck(void); 932 933 /*! ********************************************************************************* 934 * \brief Disable the 802.15.4 radio Auto Acknowledge 935 * 936 ********************************************************************************** */ 937 void PhyDisableAutoAck(void); 938 #endif 939 940 #if (TX_POWER_LIMIT_FEATURE == 1) 941 /*! ********************************************************************************* 942 * \brief This function will set max tx power limit as per txPowerLimit byte. 943 * 944 * \param txPowerLimit 945 * txPowerLimit (0 or default value), No power backoff is applied 946 * txPowerLimit = 1 to 44, force TX power back off to txPowerLimit 947 * (txPowerLimit = 0.5dBm step, TX power back off : 0.5dBm step ) 948 * If > 44 : gPhyMaxTxPowerLevel_d is used. 949 * \return txPowerLimit really stored in gPhyChannelTxPowerLimits 950 */ 951 uint8_t PhySetTxPowerLimit(uint8_t txPowerLimit); 952 953 /*! ********************************************************************************* 954 * \brief This function will get tx power limit 955 * 956 * \return txPowerLimit stored in gPhyChannelTxPowerLimits 957 */ 958 uint8_t PhyGetTxPowerLimit(void); 959 960 /*! ********************************************************************************* 961 * \brief This function will update tx power limit 962 * 963 * \return update txPowerLimit stored in gPhyChannelTxPowerLimits 964 */ 965 uint8_t PhyUpdateTxPowerLimit(void); 966 #endif 967 968 /*! ********************************************************************************* 969 * \brief This function will get CCA Configuration Values 970 * \param[in] aCca1Threshold pointer to CCA1 Threshold value 971 * \param[in] aCca2CorrThreshold pointer to CCA2 Correlation Threshold value 972 * \param[in] aCca2MinNumOfCorrTh pointer to CCA2 Minimum number of Correlation peaks 973 * 974 * \return void 975 */ 976 void PhyGetCcaConfig(uint8_t *aCca1Threshold, uint8_t *aCca2CorrThreshold, uint8_t *aCca2MinNumOfCorrTh); 977 978 /*! ********************************************************************************* 979 * \brief This function will set CCA Configuration Values 980 * \param[in] aCca1Threshold CCA1 Threshold value 981 * \param[in] aCca2CorrThreshold CCA2 Correlation Threshold value 982 * \param[in] aCca2MinNumOfCorrTh CCA2 Minimum number of Correlation peaks 983 * 984 * \return void 985 */ 986 void PhySetCcaConfig(uint8_t aCca1Threshold, uint8_t aCca2CorrThreshold, uint8_t aCca2MinNumOfCorrTh); 987 988 /* utils */ 989 uint16_t PHY_TransformArrayToUint16(uint8_t *pArray); 990 991 uint16_t PhyGetChecksum(uint8_t *pAddr, uint8_t addrMode, uint16_t PanId); 992 993 /* Indirect queue table functions */ 994 uint32_t PhyGetIndexOf(Phy_PhyLocalStruct_t *ctx, uint16_t checksum); 995 996 uint8_t PhyRemoveFromSamTable(instanceId_t instanceId, uint8_t *pAddr, uint8_t addrMode, uint16_t PanId); 997 998 uint8_t PhyAddToSapTable(instanceId_t instanceId, uint8_t *pAddr, uint8_t addrMode, uint16_t PanId); 999 1000 /* Neighbour table functions */ 1001 uint32_t PhyNbTblIndexOf(Phy_PhyLocalStruct_t *ctx, uint16_t checksum); 1002 1003 uint8_t PhyNbTblRemove(instanceId_t instanceId, uint8_t *pAddr, uint8_t addrMode, uint16_t PanId); 1004 1005 uint8_t PhyNbTblAdd(instanceId_t instanceId, uint8_t *pAddr, uint8_t addrMode, uint16_t PanId); 1006 1007 /* RADIO EVENTS */ 1008 1009 void Radio_Phy_PdDataConfirm(Phy_PhyLocalStruct_t *ctx, bool_t framePending); 1010 1011 void Radio_Phy_TimeRxTimeoutIndication(Phy_PhyLocalStruct_t *ctx); 1012 1013 void Radio_Phy_AbortIndication(Phy_PhyLocalStruct_t *ctx); 1014 1015 void Radio_Phy_PdDataIndication(Phy_PhyLocalStruct_t *ctx); 1016 1017 void Radio_Phy_TimeStartEventIndication(Phy_PhyLocalStruct_t *ctx); 1018 1019 void Radio_Phy_PlmeCcaConfirm(phyStatus_t phyChannelStatus, Phy_PhyLocalStruct_t *ctx); 1020 1021 void Radio_Phy_PlmeEdConfirm(Phy_PhyLocalStruct_t *ctx, int8_t energyLeveldB); 1022 1023 void Radio_Phy_PlmeSyncLossIndication(Phy_PhyLocalStruct_t *ctx); 1024 1025 void Radio_Phy_PlmeRxWatermark(uint32_t frameLength, uint16_t fcf); 1026 1027 void Radio_Phy_PlmeFilterFailRx(Phy_PhyLocalStruct_t *ctx); 1028 1029 bool_t PhyIsIdleRx(instanceId_t instanceId); 1030 1031 void Radio_Phy_Notify(Phy_PhyLocalStruct_t *ctx); 1032 1033 1034 void ctx_init(); 1035 void ctx_init_single(uint8_t id); 1036 Phy_PhyLocalStruct_t *ctx_get(instanceId_t id); 1037 Phy_PhyLocalStruct_t *ctx_get_current(); 1038 1039 #ifdef CTX_SCHED 1040 /* should it be in private include? */ 1041 void sched_reschedule(); 1042 1043 void ctx_set_pending(Phy_PhyLocalStruct_t *ctx); 1044 1045 bool_t ctx_is_active(Phy_PhyLocalStruct_t *ctx); 1046 bool_t ctx_is_paused(Phy_PhyLocalStruct_t *ctx); 1047 1048 void ctx_data_ind_all(Phy_PhyLocalStruct_t *ctx); 1049 1050 void ctx_set_rx_ongoing(Phy_PhyLocalStruct_t *ctx, bool_t status); 1051 1052 void ctx_set_rx(Phy_PhyLocalStruct_t *ctx); 1053 void ctx_set_tx(Phy_PhyLocalStruct_t *ctx, macToPdDataMessage_t *pMsg); 1054 void ctx_set_cca(Phy_PhyLocalStruct_t *ctx); 1055 void ctx_set_none(Phy_PhyLocalStruct_t *ctx); 1056 1057 bool_t PHY_ctx_can_sleep(); 1058 bool_t PHY_ctx_all_disabled(); 1059 1060 #else /* CTX_SCHED */ 1061 1062 #define sched_reschedule() 1063 #define ctx_set_pending(ctx) 1064 #define ctx_is_active(ctx) TRUE 1065 #define ctx_is_paused(ctx) FALSE 1066 #define ctx_data_ind_all(ctx) 1067 #define ctx_set_rx_ongoing(ctx, status) 1068 #define ctx_set_rx(ctx) 1069 #define ctx_set_tx(ctx, pMsg) 1070 #define ctx_set_cca(ctx) 1071 #define ctx_set_none(ctx) 1072 #define PHY_ctx_can_sleep() TRUE 1073 #define PHY_ctx_all_disabled() TRUE 1074 1075 #endif /* CTX_SCHED */ 1076 1077 #ifdef __cplusplus 1078 } 1079 #endif 1080 1081 #endif /* __PHY_H__ */ 1082