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