主题中讨论的其他器件: CC2652R7、 CC2652PSIP、 CC1352P、 CC2650、 CC1352P7、 CC1312R7
我正在尝试创建一个程序、使用 cc2652RSIP 来交换特定数据。
但是、"EasyLink_Status_Cmd_Error"目前正在发生、但运行不好。
此错误不会通过 EasyLink_abort 撤消。
如果有人知道发生这种情况的原因、请告诉我原因。
此外、我真的想让它成为一个程序、等待接收特定数据。
但是、这样做会导致一个错误、阻止任何内容输出到 UART。
这是为什么?
如果有人理解、请告诉我。
Lina
/* XDCtools Header files */ #include <log.h> #include <sBAN_main.h> #include <xdc/std.h> #include <xdc/runtime/System.h> /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/drivers/Power.h> #include <ti/drivers/power/PowerCC26XX.h> /* TI-RTOS Header files */ #include <ti/display/Display.h> #include <ti/drivers/GPIO.h> /* Board Header files */ #include "ti_drivers_config.h" /*======== main ========*/ int main(void) { Board_initGeneral(); GPIO_init(); log_init(); sBAN_init(); /* Start BIOS */ BIOS_start(); return (0); }
/******************************************************************************************/ /**************************************** Includes ****************************************/ /******************************************************************************************/ /* XDCtools Header files */ #include <xdc/std.h> #include <xdc/runtime/System.h> #include "sBAN_main.h" /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Semaphore.h> #include <ti/sysbios/knl/Event.h> /* Drivers */ #include <ti/drivers/rf/RF.h> #include <ti/drivers/GPIO.h> /* Board Header files */ #include "ti_drivers_config.h" /* EasyLink API Header files */ #include "easylink/EasyLink.h" /* Application Header files */ #include <ti/sysbios/knl/Clock.h> #include "log.h" #include "easylink/EasyLink.h" #include "DownLinkData.h" #include <stdlib.h> #include <stdio.h> /******************************************************************************************/ /**************************************** Defines *****************************************/ /******************************************************************************************/ /***** ADDRESS Configuration Parameter *****/ #define BAN_ID 0xaa //Hub ID #define DBEACON_ADDRESS 0xdd //Hub DBeacon Address #define CBEACON_ADDRESS 0xcc //Hub CBeacon Address /***** EVENT Task Parameter *****/ #define RADIO_EVENT_ALL 0xFFFFFFFF //Event mask #define RADIO_EVENT_TRANS_DBEACON (uint32_t)(1 << 0) //Trans DBeacon #define RADIO_EVENT_TRANS_CBEACON (uint32_t)(1 << 1) //Trans CBeacon #define RADIO_EVENT_LISTEN_CBEACON (uint32_t)(1 << 2) //Listen CBeacon #define RADIO_EVENT_LISTEN_DATA (uint32_t)(1 << 3) //Listen Node data #define RADIO_EVENT_NOMOVE (uint32_t)(1 << 4) //No move #define RADIO_EVENT_INITIAL_CREQ (uint32_t)(1 << 5) //Initial connection CReq #define RADIO_EVENT_INITIAL_CASS (uint32_t)(1 << 6) //Initial connection CAss #define RADIO_EVENT_DOWNLINK (uint32_t)(1 << 7) //Dounlink #define RADIO_EVENT_REASSIGN (uint32_t)(1 << 8) //Reassignment #define RADIO_EVENT_MIGRATION (uint32_t)(1 << 9) //ChannnelMigrationFrag #define RADIO_EVENT_ENDCONNECT (uint32_t)(1 << 10) //End connect /***** Defines *****/ #define NODE_TASK_STACK_SIZE 1024 //Hub task stack size #define NODE_TASK_PRIORITY 3 //Hub task priority #define CONCENTRATORRADIO_MAX_RETRIES 2 #define NODE_TOTAL_SLOT 6 //IBI total slots 10 #define CONCENTRATORRADIO_ACK_DELAY 250 #define CONCENTRATOR_ACTIVITY_LED CONFIG_GPIO_RLED /***** EVENT Configuration Parameter *****/ #define RADIO_SLOT_LENGTH 40 //Slot Length (ms) #define RADIO_SLOT_LENGTH_NUM 6 //Slot Length (ms) #define CONTROL_MANAGEMENT 7 //C/M Start Slot #define INACTIVE_START_SLOT 10 //Inactive start slot #define INTER_BEACON_INTERVAL_TOTAL 16 //IBI total slots 10 #define NODE_LISTEN_SLOT 3 //Default Node listen #define DBEACON_USED_CHANNEL 15 //Default Hub Channel #define NODE_SET_NUM 3 //Node can set sell num /***** Variable parameter declarations *****/ static struct CBeaconFrame CBeacon; static struct DBeaconFrame DBeacon; static struct CRequestFrame CReq; static struct CAssignmentFrame CAss; static struct AckPacket Ack; static struct testPacket tPacket; static struct ClockTimeStamp ClockTime; /***** Prototypes *****/ static void Tasksort(UArg arg0); static void NodeFunction(UArg arg0, UArg arg1); static void RxDoneCallback_CBeacon(EasyLink_CBeacon rxPacket,EasyLink_Status status); /***** Variable declarations *****/ static Task_Params NodeParams; Task_Struct NodeTask; static uint8_t NodeTaskStack[NODE_TASK_STACK_SIZE]; Event_Struct EventTask; static Event_Handle EventHandle; Clock_Struct ClockTask; static Clock_Handle ClockHandle; /*****counter or using parameter*****/ static int IBI = INTER_BEACON_INTERVAL_TOTAL; //InterBeaconInterval static int CMStartSlot=CONTROL_MANAGEMENT; //C/M Start Slot static int ISS=INACTIVE_START_SLOT; //Inactive start slot <<listen&Trans CBeacon>> static int SLen=RADIO_SLOT_LENGTH; //Slot Length static int Freq_Hz=DBEACON_USED_CHANNEL; //DBeacon channel number (19Chan 2440Hz) static int Slotnum = 0; static int DCH_Hz=DBEACON_USED_CHANNEL; //DBeacon channel number (19Chan 2440Hz) /*****slot set parameter*****/ static int sequencenum=0; //SequenceNum static int ReceiveAsync=0; //normal decision /*****cbeacom parameter*****/ static int CCAN_cnt=0; //CBeacon counter static int CCAN[3]={0,12,39}; //CBeacon Channel /*****Node Flag parameter*****/ static int SendSlot[NODE_TOTAL_SLOT]={0}; //Node Name Slot static int NodeSlot=20; //Node Data listen slot static int SelectNode; //Node set id /*****event parameter*****/ uint32_t events; //Event post pend static int EventFlag=1; //Initial connection/DownLink/Reassignment/End of connection (Event flag) /*****hub parameter*****/ uint32_t Hub_TimeSlot=0; //Hub Beacon time /*****Node parameter*****/ static int NodeID=0; //Node ID static int Node_Set=0; //Node ID set count static int NoConnect=1; //No connect flag static int NodeID_set[NODE_SET_NUM]; //Node ID set static int ConectSell[NODE_SET_NUM]={3,4,5}; //Node Time /*****clock counter or using parameter*****/ uint32_t TimeStamp_now; //Slot start time uint32_t TimeStamp_dif; //Beacon time dif uint32_t before_TimeStamp_dif; //Beacon time before dif uint32_t TimeStamp_CB; //Beacon read uint32_t TimeStamp_DB; //Beacon read enum NodeRadioOperationStatus { NodeRadioStatus_Success, NodeRadioStatus_Failed, NodeRadioStatus_FailedNotConnected, }; struct RadioOperation { EasyLink_TxPacket easyLinkTxPacket; uint8_t retriesDone; uint8_t maxNumberOfRetries; uint32_t ackTimeoutMs; enum NodeRadioOperationStatus result; }; static struct RadioOperation currentRadioOperation; /***** Function definitions *****/ void sBAN_init(void) { /* Set config of LED pin */ GPIO_setConfig(CONCENTRATOR_ACTIVITY_LED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW); /* Create Clock event */ Clock_Params clkParams; Clock_Params_init(&clkParams); clkParams.period =100*SLen/*ms*/; clkParams.startFlag = FALSE; Clock_construct(&ClockTask, (Clock_FuncPtr)Tasksort,1000, &clkParams); ClockHandle =Clock_handle(&ClockTask); /* Create event used internally for state changes */ Event_Params eventParam; Event_Params_init(&eventParam); Event_construct(&EventTask, &eventParam); EventHandle = Event_handle(&EventTask); /* Create the concentrator radio protocol task */ Task_Params_init(&NodeParams); NodeParams.stackSize = NODE_TASK_STACK_SIZE; NodeParams.priority = NODE_TASK_PRIORITY; NodeParams.stack = &NodeTaskStack; Task_construct(&NodeTask, NodeFunction, &NodeParams, NULL); } /******************************************************************************************/ static void NodeFunction(UArg arg0, UArg arg1) { // Initialize the EasyLink parameters to their default values EasyLink_Params easyLink_params; easyLink_params.ui32ModType=EasyLink_Phy_625bpsLrm; //easyLink_params.pClientEventCb=0; //callback function //easyLink_params.nClientEventMask=0; //Client event mask //easyLink_params.pGrnFxn=0; EasyLink_Params_init(&easyLink_params); /* Initialize EasyLink */ if(EasyLink_init(&easyLink_params) != EasyLink_Status_Success){ usprintf_mng("EasyLink_init failed");} /* Frequency & Clock settings */ usprintf_mng("abort:%d\n",EasyLink_abort()); EasyLink_setFrequency_SET(0); usprintf_mng("Freq_Hz:%d\n",EasyLink_getFrequency()/10000); //ListenCB(); while(1){ //usprintf_mng("abort:%d\n",EasyLink_abort()); //if(EasyLink_transmit(¤tRadioOperation.easyLinkTxPacket) != EasyLink_Status_Success) // {usprintf_mng("EasyLink_receive_CBeacon failed");} //if(EasyLink_receive(&RrxPacket) != EasyLink_Status_Success) //{usprintf_mng("EasyLink_receive_CBeacon failed");} //if(EasyLink_receive_CBeacon(&CBeacon) != EasyLink_Status_Success) // {usprintf_mng("EasyLink_receive_CBeacon failed");} usprintf_mng("abort:%d\n",EasyLink_abort()); /* Clock settings */ ClockTime.EndTime=RF_getCurrentTime()+10*4000; /*receive C-Beacon*/ if(EasyLink_receiveAsync_CBeacon(RxDoneCallback_CBeacon,&CBeacon,ClockTime) != EasyLink_Status_Success) {usprintf_mng("EasyLink_receiveAsync failed\n");} usprintf_mng("abort:%d\n",EasyLink_abort()); TimeStamp_CB=(RF_getCurrentTime()/4000); sequencenum=sequencenum+1; /*Cbeacon address = 0xcc.check*/ //if(CBeacon.fCBeacon.HubAddr==CBEACON_ADDRESS && CBeacon.fCBeacon.InitialState==0){ //if(CBeacon.fCBeacon.HubAddr==CBEACON_ADDRESS){ if(sequencenum==100){ //etc.. break; }else{ usprintf_mng(">>***Can't InitialState***<<\n"); } } /* Frequency & Clock settings */ usprintf_mng("abort:%d\n",EasyLink_abort()); EasyLink_setFrequency_SET(Freq_Hz); usprintf_mng("Freq_Hz:%d\n",EasyLink_getFrequency()/1000); //ListenDB(); //Clock_match(); usprintf_mng("Start Node clock\n\n"); Clock_start(ClockHandle); while (1) { uint32_t events = Event_pend(EventHandle, 0, RADIO_EVENT_ALL, BIOS_WAIT_FOREVER); /********************** Transmission DBeacon ***********************/ if(events & RADIO_EVENT_TRANS_DBEACON) { /* Frequency & Clock settings */ usprintf_mng("abort:%d\n",EasyLink_abort()); EasyLink_setFrequency(24020000+Freq_Hz*20000); usprintf_mng("Freq_Hz:%d\n",EasyLink_getFrequency()/1000); ClockTime.StartTime=RF_getCurrentTime()+20*4000; /* DBeacon settings */ DBeacon.fDBeacon.HubAddr=DBEACON_ADDRESS; //DBeacon Address DBeacon.fDBeacon.IBI_Totalslots=IBI; //IBI DBeacon.fDBeacon.CMStartSlot=CMStartSlot; //CMS Start Slot DBeacon.fDBeacon.InactiveStartSlot=ISS; //Inactive period Start Slot DBeacon.fDBeacon.DownlinkData=0; //DownLink flag DBeacon.fDBeacon.SlotReassignment=0; //CASS DBeacon.fDBeacon.ChannelMigration=0; //Channel Migration DBeacon.fDBeacon.MultiuseAccess=0; //No used (Multi-use Access) DBeacon.fDBeacon.TimeStamp=Hub_TimeSlot; //Time stamp 32bit DBeacon.fDBeacon.DSRList=0; //Node ID DBeacon.fDBeacon.SlotReassignmentTimung=0; //Re timing DBeacon.fDBeacon.ChangeTiming=0; //Re Channel timing DBeacon.fDBeacon.ChannelNumber=DCH_Hz; //Used Channel Number 19 DBeacon.fDBeacon.Reserved=0; if(EasyLink_transmit_DBeacon(&DBeacon,ClockTime) != EasyLink_Status_Success) {usprintf_mng("EasyLink_transmitAsync failed");} } /*********************** No move ***********************/ if(events&RADIO_EVENT_NOMOVE){ /* No move */ //usprintf_mng("\n"); // if(EventFlag>10){ // EventFlag=EventFlag-9; // } } } } /******************************************************************************************/ static void Tasksort(UArg arg0) { /*Timer*/ Hub_TimeSlot=(RF_getCurrentTime()/4000); /*Counter*/ sequencenum++; Slotnum=sequencenum%IBI; ReceiveAsync=0; usprintf_mng("\n"); usprintf_mng("%d[%03dms]",Slotnum,Hub_TimeSlot); /********************** Transmit DBeacon timing ***********************/ if(Slotnum == 0){ /* Transmit DBeacon */ Event_post(EventHandle, RADIO_EVENT_TRANS_DBEACON); } /*********************** else timing ***********************/ else{ /* No Event time slot */ Event_post(EventHandle, RADIO_EVENT_NOMOVE); } } /******************************************************************************************/ static void RxDoneCallback_CBeacon(EasyLink_CBeacon rxPacket,EasyLink_Status status) { CBeacon=rxPacket; if (status == EasyLink_Status_Success) { /*CAss packet received*/ ReceiveAsync=1; //usprintf_mng("ReCB[%03dms]:ok\n",(RF_getCurrentTime()/4000)); Event_post(EventHandle, RADIO_EVENT_NOMOVE); } else { /* error timeout*/ //usprintf_mng("ReCB[%03dms]:abort\n",(RF_getCurrentTime()/4000)); Event_post(EventHandle, RADIO_EVENT_NOMOVE); } }
/***** Includes *****/ #include "EasyLink.h" #include "ti_easylink_config.h" #include <stdbool.h> #include <stdint.h> #include <stddef.h> #include <limits.h> #include <ti/drivers/rf/RF.h> /* TI Drivers */ #include <ti_drivers_config.h> #include <ti_radio_config.h> /* BIOS Header files */ #include <ti/sysbios/knl/Clock.h> #include <ti/sysbios/knl/Semaphore.h> #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> /* XDCtools Header files */ #include <xdc/runtime/Error.h> #include <ti/devices/DeviceFamily.h> #include "log.h" #include DeviceFamily_constructPath(driverlib/rf_data_entry.h) #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h) #include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h) #include DeviceFamily_constructPath(driverlib/chipinfo.h) #include DeviceFamily_constructPath(inc/hw_memmap.h) #include DeviceFamily_constructPath(inc/hw_fcfg1.h) #include DeviceFamily_constructPath(inc/hw_ccfg.h) #include DeviceFamily_constructPath(inc/hw_ccfg_simple_struct.h) union setupCmd_t{ #if ((defined LAUNCHXL_CC1352P1) || (defined LAUNCHXL_CC1352P_2) || \ (defined LAUNCHXL_CC1352P_4)|| (defined LP_CC1352P7_1) || \ (defined LP_CC1352P7_4) || (defined CONFIG_LP_CC2652PSIP) || \ (defined CONFIG_CC2652P1FSIP)) rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t divSetup; #else rfc_CMD_PROP_RADIO_DIV_SETUP_t divSetup; #endif rfc_CMD_PROP_RADIO_SETUP_t setup; }; // Enable Activity profiling // #define EASYLINK_ACTIVITY_PROFILING //Primary IEEE address location #define EASYLINK_PRIMARY_IEEE_ADDR_LOCATION (FCFG1_BASE + FCFG1_O_MAC_15_4_0) //Secondary IEEE address location #define EASYLINK_SECONDARY_IEEE_ADDR_LOCATION (CCFG_BASE + CCFG_O_IEEE_MAC_0) #define EASYLINK_RF_EVENT_MASK ( RF_EventLastCmdDone | \ RF_EventCmdAborted | RF_EventCmdStopped | RF_EventCmdCancelled | \ RF_EventCmdPreempted ) #define EASYLINK_RF_CMD_HANDLE_INVALID -1 #define EasyLink_CmdHandle_isValid(handle) (handle >= 0) /* EasyLink Proprietary Header Configuration */ #define EASYLINK_PROP_TRX_SYNC_WORD 0x930B51DE #define EASYLINK_PROP_HDR_NBITS 8U #define EASYLINK_PROP_LEN_OFFSET 0U /* IEEE 802.15.4g Header Configuration * _S indicates the shift for a given bit field * _M indicates the mask required to isolate a given bit field */ #define EASYLINK_IEEE_TRX_SYNC_WORD 0x0055904E #define EASYLINK_IEEE_HDR_NBITS 16U #define EASYLINK_IEEE_LEN_OFFSET 0xFC #define EASYLINK_IEEE_HDR_LEN_S 0U #define EASYLINK_IEEE_HDR_LEN_M 0x00FFU #define EASYLINK_IEEE_HDR_CRC_S 12U #define EASYLINK_IEEE_HDR_CRC_M 0x1000U #define EASYLINK_IEEE_HDR_WHTNG_S 11U #define EASYLINK_IEEE_HDR_WHTNG_M 0x0800U #define EASYLINK_IEEE_HDR_CRC_2BYTE 1U #define EASYLINK_IEEE_HDR_CRC_4BYTE 0U #define EASYLINK_IEEE_HDR_WHTNG_EN 1U #define EASYLINK_IEEE_HDR_WHTNG_DIS 0U #define EASYLINK_IEEE_HDR_CREATE(crc, whitening, length) { \ ((crc << EASYLINK_IEEE_HDR_CRC_S) | (whitening << EASYLINK_IEEE_HDR_WHTNG_S) | \ ((length << EASYLINK_IEEE_HDR_LEN_S) & EASYLINK_IEEE_HDR_LEN_M)) \ } /* Common Configuration (Prop and IEEE) */ #define EASYLINK_HDR_LEN_NBITS 8U /* Return the size of the header rounded up to * the nearest integer number of bytes */ #define EASYLINK_HDR_SIZE_NBYTES(x) (((x) >> 3U) + (((x) & 0x03) ? 1U : 0U)) /* 2-GFSK 50 Kbps baud rate in kbps */ #define BAUD_RATE_2GFSK_50K (50U) /* 2-GFSK 200 Kbps baud rate in kbps */ #define BAUD_RATE_2GFSK_200K (200U) /* SLR chip rate in kcps */ #define BAUD_RATE_SLR_5K (20U) /* Payload length in terms of chips */ #define PKT_NCHIPS_SLR_5K (32U) /* Packet overhead in terms of chips */ #define PKT_OVHD_SLR_5K (480U) /* Packet overhead in terms of bits */ #define PKT_OVHD_2GFSK_50K (10U) /* Packet overhead in terms of bits */ #define PKT_OVHD_2GFSK_200K (10U) /***** Prototypes *****/ static EasyLink_TxDoneCb txCb; static EasyLink_ReceiveCb rxCb; static EasyLink_CBReceiveCb CBrxCb; static EasyLink_GetRandomNumber getRN; /***** Variable declarations *****/ static RF_Object rfObject; static RF_Handle rfHandle; //Rx buffer includes data entry structure, hdr (len=1byte), dst addr (max of 8 bytes) and data //which must be aligned to 4B #if defined(__TI_COMPILER_VERSION__) #pragma DATA_ALIGN (rxBuffer, 4); #elif defined(__IAR_SYSTEMS_ICC__) #pragma data_alignment = 4 #elif defined(__GNUC__) __attribute__((aligned(4))) #else #error This compiler is not supported. #endif static uint8_t rxBuffer[sizeof(rfc_dataEntryGeneral_t) + 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH]; static dataQueue_t dataQueue; static rfc_propRxOutput_t rxStatistics; //Tx buffer includes hdr (len=1 or 2 bytes), dst addr (max of 8 bytes) and data static uint8_t txBuffer[2U + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH]; // Addr size for Filter and Tx/Rx operations // Set default to 1 byte addr to work with SmartRF studio default settings // NOTE that it can take on values in the range [0, EASYLINK_MAX_ADDR_SIZE] static uint8_t addrSize = EASYLINK_ADDR_SIZE; // Default address transmitted when EASYLINK_USE_DEFAULT_ADDR = true static uint8_t defaultAddr[8] = EASYLINK_DEFAULT_ADDR; // Header Size (in bytes) for Advanced Tx operations. For IEEE 802.15.4g modes // it is 2 bytes, 1 for the rest static uint8_t hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); //Indicating that the API is initialized static uint8_t configured = 0; //Indicating that the API suspended static uint8_t suspended = 0; //Use an IEEE header for the Tx/Rx command static bool useIeeeHeader = 0; //RF Params allowing configuration of the inactivity timeout, which is the time //it takes for the radio to shut down when there are no commands in the queue static RF_Params rfParams; static bool rfParamsConfigured = 0; //Flag used to indicate the multi client operation is enabled static bool rfModeMultiClient = EASYLINK_ENABLE_MULTI_CLIENT; //Async Rx timeout value static uint32_t asyncRxTimeOut = EASYLINK_ASYNC_RX_TIMEOUT; // Current Command Priority static uint32_t cmdPriority = EasyLink_Priority_Normal; //local commands, contents will be defined by modulation type static union setupCmd_t EasyLink_cmdPropRadioSetup; static rfc_CMD_FS_t EasyLink_cmdFs; static RF_Mode EasyLink_RF_prop; static rfc_CMD_PROP_TX_ADV_t EasyLink_cmdPropTxAdv; static rfc_CMD_PROP_RX_ADV_t EasyLink_cmdPropRxAdv; static rfc_CMD_PROP_CS_t EasyLink_cmdPropCs; // The table for setting the Rx Address Filters #if defined(__TI_COMPILER_VERSION__) #pragma DATA_ALIGN (addrFilterTable, 4); #elif defined(__IAR_SYSTEMS_ICC__) #pragma data_alignment = 4 #elif defined(__GNUC__) __attribute__((aligned(4))) #endif static uint8_t addrFilterTable[EASYLINK_MAX_ADDR_FILTERS * EASYLINK_MAX_ADDR_SIZE] = EASYLINK_ADDR_FILTER_TABLE; // Used as a pointer to an entry in the EasyLink_rfSettings array static EasyLink_RfSetting *rfSetting = 0; // Default inactivity timeout of 1 ms static uint32_t inactivityTimeout = EASYLINK_IDLE_TIMEOUT; //Mutex for locking the RF driver resource static Semaphore_Handle busyMutex; //Handle for last Async command, which is needed by EasyLink_abort static RF_CmdHandle asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID; // Command schedule parameters, needed by the DMM to schedule commands in a // multi-client setup static RF_ScheduleCmdParams schParams_prop; /* Set Default parameters structure */ static const EasyLink_Params EasyLink_defaultParams = EASYLINK_PARAM_CONFIG; static EasyLink_Params EasyLink_params; //*****************************************************************************// // Check the address size (in bytes) in the range [0, EASYLINK_MAX_ADDR_SIZE] static bool isAddrSizeValid(uint8_t ui8AddrSize) { return((ui8AddrSize == 0) || (ui8AddrSize <= EASYLINK_MAX_ADDR_SIZE)); } //*****************************************************************************// void EasyLink_Params_init(EasyLink_Params *params) { *params = EasyLink_defaultParams; } //*****************************************************************************// // Generate the activity table value static uint32_t genActivityTableValue(EasyLink_Activity activity, EasyLink_Priority priority) { return((activity << 16) | priority); } //*****************************************************************************// //Create an Advanced Tx command from a Tx Command void createTxAdvFromTx(rfc_CMD_PROP_TX_ADV_t *dst, rfc_CMD_PROP_TX_t *src) { memset(dst, 0 , sizeof(rfc_CMD_PROP_TX_ADV_t)); dst->commandNo = CMD_PROP_TX_ADV; memcpy(&(dst->status), &(src->status), offsetof(rfc_CMD_PROP_TX_ADV_t, pktConf) - offsetof(rfc_CMD_PROP_TX_ADV_t, status)); dst->pktConf.bFsOff = src->pktConf.bFsOff; dst->pktConf.bUseCrc = src->pktConf.bUseCrc; dst->pktLen = src->pktLen; dst->syncWord = src->syncWord; } //*****************************************************************************// //Callback for Async Tx complete static void txDoneCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { EasyLink_Status status; //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID; if (e & RF_EventLastCmdDone) { status = EasyLink_Status_Success; } else if ( (e & RF_EventCmdAborted) || (e & RF_EventCmdCancelled) || (e & RF_EventCmdPreempted) ) { status = EasyLink_Status_Aborted; } else if(e == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else { status = EasyLink_Status_Tx_Error; } if (txCb != NULL) { txCb(status); } } //*****************************************************************************// // Calculate the command time for a given txPacket in ms static uint32_t calculateCmdTime(EasyLink_TxPacket *txPacket) { uint32_t cmdTime = 0; if(EasyLink_params.ui32ModType == EasyLink_Phy_5kbpsSlLr) { /* calculate the command time for the packet format: * * +--------+--------+--------+----------------------------+-----+----+ * |INV_SYNC|INV_SYNC|SYNCWORD|_____PAYLOAD(LEN + 1)_______|_CRC_|TERM| * | | | |__LEN__|ADDR|____DATA_______| | | * | | | | | (A)| | | | * | 64S | 64S | 64S | 1B |1-8B| 'LEN-A' B | 2B | 7B | * +--------+--------+--------+-------+--------------------+-----+----+ * <----------pktlen----------> * S - symbols, B -bytes * Time-of-Flight, * nsymbols = (M+1)*SYNCWORD + LEN + ADDR + DATA + CRC + TERM * = (M+1)*64 + (pktlen + CRC + TERM)*8*2*DSSS * = 3*64 + (pktlen+9)*32 * = pktlen*32 + 480 * M - number of inverted sync words (RF_cmdPropRadioDivSetup_sl_lr.preamConf.nPreamBytes) * DSSS - spreading factor of 2, set in the overrides * * TOF (ms) = (nsymbols/symbol_rate)*1e3 * = (pktlen*32 + 480 / 20e3)*1e3 * = (pktlen*32 + 480 / 20) */ cmdTime = (EasyLink_cmdPropTxAdv.pktLen*PKT_NCHIPS_SLR_5K + PKT_OVHD_SLR_5K) / BAUD_RATE_SLR_5K; } else if(EasyLink_params.ui32ModType == EasyLink_Phy_200kbps2gfsk) { /* calculate the command time for the packet format: * * +----------+----------+----------------------------+-----+ * |_PREAMBLE_|_SYNCWORD_|_____PAYLOAD(LEN + 1)_______|_CRC_| * | | |__HDR__|ADDR|____DATA_______| | * | | | LEN | (A)| | | * | 4B | 4B | 2B |1-8B| 'LEN-A' B | 2B | * +----------+----------+-------+--------------------+-----+ * <----------pktlen----------> * Time-of-Flight, * TOF(ms) = (PREAMBLE + SYNCWORD + LEN + ADDR + DATA + CRC) * 8bits/200kbps *1e3 * = (pktlen + 10) * 8/200k */ cmdTime = ((EasyLink_cmdPropTxAdv.pktLen + PKT_OVHD_2GFSK_200K) * CHAR_BIT) / BAUD_RATE_2GFSK_200K; } else //assume 50kbps { /* calculate the command time for the packet format: * * +----------+----------+----------------------------+-----+ * |_PREAMBLE_|_SYNCWORD_|_____PAYLOAD(LEN + 1)_______|_CRC_| * | | |__LEN__|ADDR|____DATA_______| | * | | | | (A)| | | * | 4B | 4B | 1B |1-8B| 'LEN-A' B | 2B | * +----------+----------+-------+--------------------+-----+ * <----------pktlen----------> * Time-of-Flight, * TOF(ms) = (PREAMBLE + SYNCWORD + LEN + ADDR + DATA + CRC) * 8bits/50kbps *1e3 * = (pktlen + 10) * 8/50k */ cmdTime = ((EasyLink_cmdPropTxAdv.pktLen + PKT_OVHD_2GFSK_50K) * CHAR_BIT) / BAUD_RATE_2GFSK_50K; } return (cmdTime); } //*****************************************************************************// //Callback for Clear Channel Assessment Done static void ccaDoneCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { EasyLink_Status status = EasyLink_Status_Tx_Error; RF_Op* pCmd = RF_getCmdOp(h, ch); bool bCcaRunAgain = false; static uint8_t be = EASYLINK_MIN_CCA_BACKOFF_WINDOW; static uint32_t backOffTime; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID; if (e & RF_EventLastCmdDone) { if(pCmd->status == PROP_DONE_IDLE) { // Carrier Sense operation ended with an idle channel, // and the next op (TX) should have already taken place // Failure to transmit is reflected in the default status, // EasyLink_Status_Tx_Error, being set if(pCmd->pNextOp->status == PROP_DONE_OK) { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); status = EasyLink_Status_Success; // Reset the number of retries be = EASYLINK_MIN_CCA_BACKOFF_WINDOW; } } else if(pCmd->status == PROP_DONE_BUSY) { if(be > EASYLINK_MAX_CCA_BACKOFF_WINDOW) { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); // Reset the number of retries be = EASYLINK_MIN_CCA_BACKOFF_WINDOW; // CCA failed max number of retries status = EasyLink_Status_Busy_Error; } else { // The back-off time is a random number chosen from 0 to 2^be, // where 'be' goes from EASYLINK_MIN_CCA_BACKOFF_WINDOW // to EASYLINK_MAX_CCA_BACKOFF_WINDOW. This number is then converted // into EASYLINK_CCA_BACKOFF_TIMEUNITS units, and subsequently used to // schedule the next CCA sequence. The variable 'be' is incremented each // time, up to a pre-configured maximum, the back-off algorithm is run. backOffTime = (getRN() & ((1 << be++)-1)) * EasyLink_us_To_RadioTime(EASYLINK_CCA_BACKOFF_TIMEUNITS); // running CCA again bCcaRunAgain = true; // The random number generator function returns a value in the range // 0 to 2^15 - 1 and we choose the 'be' most significant bits as our // back-off time in milliseconds (converted to RAT ticks) pCmd->startTime = RF_getCurrentTime() + backOffTime; // post the chained CS+TX command again while checking // for a clear channel (CCA) before sending a packet if(rfModeMultiClient) { schParams_prop.startTime = pCmd->startTime; schParams_prop.startType = RF_StartAbs; asyncCmdHndl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropCs, &schParams_prop, ccaDoneCallback, EASYLINK_RF_EVENT_MASK); } else { asyncCmdHndl = RF_postCmd(h, (RF_Op*)&EasyLink_cmdPropCs, RF_PriorityHigh, ccaDoneCallback, EASYLINK_RF_EVENT_MASK); } if(EasyLink_CmdHandle_isValid(asyncCmdHndl) == false) { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); // Reset the number of retries be = EASYLINK_MIN_CCA_BACKOFF_WINDOW; } } } else { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); // Reset the number of retries be = EASYLINK_MIN_CCA_BACKOFF_WINDOW; // The CS command status should be either IDLE or BUSY, // all other status codes can be considered errors // Status is set to the default, EasyLink_Status_Tx_Error } } else if ((e & RF_EventCmdAborted) || (e & RF_EventCmdCancelled) || (e & RF_EventCmdPreempted)) { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); // Reset the number of retries be = EASYLINK_MIN_CCA_BACKOFF_WINDOW; if(e == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else { status = EasyLink_Status_Aborted; } } else { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); // Reset the number of retries be = EASYLINK_MIN_CCA_BACKOFF_WINDOW; // Status is set to the default, EasyLink_Status_Tx_Error } if ((txCb != NULL) && (!bCcaRunAgain)) { txCb(status); } } //Callback for Async Rx complete //*****************************************************************************// static void rxDoneCallback_CBeacon(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { unsigned char bitArray[8] = {0}; /* initialization */ static EasyLink_CBeacon rxPacket; rxPacket.fCBeacon.TimeStamp=0; rxPacket.fCBeacon.InitialState=0; rxPacket.fCBeacon.DCHChannelNum=0; rxPacket.fCBeacon.DutyCycling=0; rxPacket.fCBeacon.InterferenceMitigation=0; rxPacket.fCBeacon.Reser_1=0; rxPacket.fCBeacon.TimeSlots=0; rxPacket.fCBeacon.SlotLen=0; rxPacket.fCBeacon.HubAddr=0; EasyLink_Status status = EasyLink_Status_Rx_Error; rfc_dataEntryGeneral_t *pDataEntry; pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer; rxPacket.len = *(uint8_t*)(&pDataEntry->data); memcpy(bitArray, (&pDataEntry->data+1), rxPacket.len); usprintf_mng("test:%02x %02x %02x %02x %02x %02x %02x %02x\n", bitArray[0],bitArray[1],bitArray[2],bitArray[3],bitArray[4],bitArray[5],bitArray[6],bitArray[7]); if (e & RF_EventLastCmdDone) { usprintf_mng("E0\n"); Semaphore_post(busyMutex); //Release now so user callback can call EasyLink API's asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID; if (EasyLink_cmdPropRxAdv.status == PROP_DONE_OK) //Check command status { if (pDataEntry->status != DATA_ENTRY_FINISHED) //Check that data entry status indicates it is finished with { usprintf_mng("E1\n"); status = EasyLink_Status_Rx_Error; } else if ( (rxStatistics.nRxOk == 1) || ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) && (rxStatistics.nRxIgnored == 1)) ) { //copy length from pDataEntry //rxPacket.len = *(uint8_t*)(&pDataEntry->data) - addrSize; rxPacket.len = *(uint8_t*)(&pDataEntry->data); if(useIeeeHeader) {hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS);} else {hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS);} //copy address from packet payload (as it is not in hdr) //memcpy(&rxPacket.dstAddr, (&pDataEntry->data + hdrSize), addrSize); if(EASYLINK_MAX_DATA_LENGTH >= rxPacket.len) { //copy payload //memcpy(&rxPacket.payload, (&pDataEntry->data + hdrSize + addrSize), rxPacket.len); //rxPacket.rssi = rxStatistics.lastRssi; //rxPacket.absTime = rxStatistics.timeStamp; memcpy(bitArray, (&pDataEntry->data+1), rxPacket.len); usprintf_mng("Receve:%02x %02x %02x %02x %02x %02x %02x %02x\n", bitArray[0],bitArray[1],bitArray[2],bitArray[3],bitArray[4],bitArray[5],bitArray[6],bitArray[7]); /*****************************************/ rxPacket.fCBeacon.TimeStamp=NULL; //Make any bit 32 TimeStamp rxPacket.fCBeacon.TimeStamp|=bitArray[7]; rxPacket.fCBeacon.TimeStamp|=bitArray[6]<<8; rxPacket.fCBeacon.TimeStamp|=bitArray[5]<<16; rxPacket.fCBeacon.TimeStamp|=bitArray[4]<<24; rxPacket.fCBeacon.InitialState=NULL; //Make any bit 1 InitialState rxPacket.fCBeacon.InitialState|=bitArray[3]&0x01; rxPacket.fCBeacon.DCHChannelNum=NULL; //Make any bit 6 DCHChannelNum rxPacket.fCBeacon.DCHChannelNum|=(bitArray[3]&0x7e)>>1; rxPacket.fCBeacon.DutyCycling=NULL; //Make any bit 2 DutyCycling rxPacket.fCBeacon.DutyCycling|=(bitArray[3]&0x80)>>7; rxPacket.fCBeacon.DutyCycling|=(bitArray[2]&0x01)<<1; rxPacket.fCBeacon.InterferenceMitigation=NULL; //Make any bit 1 InterferenceMitigation rxPacket.fCBeacon.InterferenceMitigation|=(bitArray[2]&0x02)>>1; rxPacket.fCBeacon.Reser_1=NULL; //Make any bit 1 Reserved rxPacket.fCBeacon.Reser_1|=(bitArray[2]&0x04)>>2; rxPacket.fCBeacon.TimeSlots=NULL; //Make any bit 10 TimeSlots rxPacket.fCBeacon.TimeSlots|=(bitArray[2]&0xf8)>>3; rxPacket.fCBeacon.TimeSlots|=(bitArray[1]&0x1f)<<5; rxPacket.fCBeacon.SlotLen=NULL; //Make any bit 3 SlotLen rxPacket.fCBeacon.SlotLen|=(bitArray[1]&0xe0)>>5; rxPacket.fCBeacon.HubAddr=bitArray[0]; //Make any bit 8 HubAddr /******************************************/ status = EasyLink_Status_Success; } else { // Packet payload too long status = EasyLink_Status_Rx_Buffer_Error; } } else if ( rxStatistics.nRxBufFull == 1) { status = EasyLink_Status_Rx_Buffer_Error; } else if ( rxStatistics.nRxStopped == 1) { status = EasyLink_Status_Aborted; } else { usprintf_mng("E2\n"); status = EasyLink_Status_Rx_Error; } } else if ( EasyLink_cmdPropRxAdv.status == PROP_DONE_RXTIMEOUT) { status = EasyLink_Status_Rx_Timeout; } else { usprintf_mng("E3\n"); status = EasyLink_Status_Rx_Error; } } else if (e & (RF_EventCmdCancelled | RF_EventCmdAborted | RF_EventCmdPreempted | RF_EventCmdStopped)) { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID; if(e == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else { status = EasyLink_Status_Aborted; } } //if (rxCb != NULL){rxCb(&rxPacket, status);} if (CBrxCb != NULL) { CBrxCb(rxPacket,status); } usprintf_mng("Status%d\n",status); usprintf_mng("msgcard:%d\n",RF_flushCmd(h,ch,0)); RF_flushCmd(h,ch,0); } //Callback for Async Rx complete //*****************************************************************************// static void rxDoneCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { EasyLink_Status status = EasyLink_Status_Rx_Error; //create rxPacket as a static so that the large payload buffer it is not //allocated from the stack static EasyLink_RxPacket rxPacket; rfc_dataEntryGeneral_t *pDataEntry; pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer; if (e & RF_EventLastCmdDone) { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID; //Check command status if (EasyLink_cmdPropRxAdv.status == PROP_DONE_OK) { //Check that data entry status indicates it is finished with if (pDataEntry->status != DATA_ENTRY_FINISHED) { status = EasyLink_Status_Rx_Error; } else if ( (rxStatistics.nRxOk == 1) || //or filer disabled and ignore due to addr mistmatch ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) && (rxStatistics.nRxIgnored == 1)) ) { //copy length from pDataEntry rxPacket.len = *(uint8_t*)(&pDataEntry->data) - addrSize; if(useIeeeHeader) { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); } else { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); } //copy address from packet payload (as it is not in hdr) memcpy(&rxPacket.dstAddr, (&pDataEntry->data + hdrSize), addrSize); if(EASYLINK_MAX_DATA_LENGTH >= rxPacket.len) { //copy payload memcpy(&rxPacket.payload, (&pDataEntry->data + hdrSize + addrSize), rxPacket.len); rxPacket.rssi = rxStatistics.lastRssi; rxPacket.absTime = rxStatistics.timeStamp; status = EasyLink_Status_Success; } else { // Packet payload too long status = EasyLink_Status_Rx_Buffer_Error; } } else if ( rxStatistics.nRxBufFull == 1) { status = EasyLink_Status_Rx_Buffer_Error; } else if ( rxStatistics.nRxStopped == 1) { status = EasyLink_Status_Aborted; } else { status = EasyLink_Status_Rx_Error; } } else if ( EasyLink_cmdPropRxAdv.status == PROP_DONE_RXTIMEOUT) { status = EasyLink_Status_Rx_Timeout; } else { status = EasyLink_Status_Rx_Error; } } else if (e & (RF_EventCmdCancelled | RF_EventCmdAborted | RF_EventCmdPreempted | RF_EventCmdStopped)) { //Release now so user callback can call EasyLink API's Semaphore_post(busyMutex); asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID; if(e == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else { status = EasyLink_Status_Aborted; } } if (rxCb != NULL) { rxCb(&rxPacket, status); } } //*****************************************************************************// //Callback for Async TX Test mode static void asyncCmdCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { Semaphore_post(busyMutex); asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID; } //*****************************************************************************// static EasyLink_Status enableTestMode(EasyLink_CtrlOption mode) { EasyLink_Status status = EasyLink_Status_Cmd_Error; //This needs to be static as it is used by the RF driver and Modem after //this function exits static rfc_CMD_TX_TEST_t txTestCmd = {0}; static rfc_CMD_RX_TEST_t rxTestCmd = {0}; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Rx, (EasyLink_Priority)cmdPriority); if((!configured) || suspended) { return EasyLink_Status_Config_Error; } if((mode != EasyLink_Ctrl_Test_Tone) && (mode != EasyLink_Ctrl_Test_Signal) && (mode != EasyLink_Ctrl_Rx_Test_Tone)) { return EasyLink_Status_Param_Error; } if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { return EasyLink_Status_Busy_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } if((mode == EasyLink_Ctrl_Test_Tone) || (mode == EasyLink_Ctrl_Test_Signal)) { txTestCmd.commandNo = CMD_TX_TEST; txTestCmd.startTrigger.triggerType = TRIG_NOW; txTestCmd.startTrigger.pastTrig = 1; txTestCmd.startTime = 0; txTestCmd.config.bFsOff = 1; txTestCmd.syncWord = EasyLink_cmdPropTxAdv.syncWord; /* WhitenMode * 0: No whitening * 1: Default whitening * 2: PRBS-15 * 3: PRBS-32 */ txTestCmd.config.whitenMode = EASYLINK_WHITENING_MODE; //set tone (unmodulated) or signal (modulated) if (mode == EasyLink_Ctrl_Test_Tone) { txTestCmd.txWord = 0xFFFF; txTestCmd.config.bUseCw = 1; } else { txTestCmd.txWord = 0xAAAA; txTestCmd.config.bUseCw = 0; } //generate continuous test signal txTestCmd.endTrigger.triggerType = TRIG_NEVER; /* Post command and store Cmd Handle for future abort */ if(rfModeMultiClient) { asyncCmdHndl = RF_scheduleCmd(rfHandle, (RF_Op*)&txTestCmd, &schParams_prop, asyncCmdCallback, EASYLINK_RF_EVENT_MASK); } else { asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&txTestCmd, RF_PriorityNormal, asyncCmdCallback, EASYLINK_RF_EVENT_MASK); } /* Has command completed? */ uint16_t count = 0; while (txTestCmd.status != ACTIVE) { //The command did not complete as fast as expected, sleep for 10ms Task_sleep(10000 / Clock_tickPeriod); if (count++ > 500) { //Should not get here, if we did Something went wrong with the //the RF Driver, get out of here and return an error. //The next command will likely lock up. break; } } if (txTestCmd.status == ACTIVE) { status = EasyLink_Status_Success; } } else // mode is EasyLink_Ctrl_Rx_Test_Tone { rxTestCmd.commandNo = CMD_RX_TEST; rxTestCmd.startTrigger.triggerType = TRIG_NOW; rxTestCmd.startTrigger.pastTrig = 1; rxTestCmd.startTime = 0; rxTestCmd.config.bFsOff = 1; // Correlation threshold set to max to prevent sync, as RSSI values // are locked after sync rxTestCmd.config.bNoSync = 1; rxTestCmd.syncWord = EasyLink_cmdPropRxAdv.syncWord0; //detect test signal continuously rxTestCmd.endTrigger.triggerType = TRIG_NEVER; /* Post command and store Cmd Handle for future abort */ if(rfModeMultiClient) { asyncCmdHndl = RF_scheduleCmd(rfHandle, (RF_Op*)&rxTestCmd, &schParams_prop, txDoneCallback, EASYLINK_RF_EVENT_MASK); } else { asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&rxTestCmd, RF_PriorityNormal, asyncCmdCallback, EASYLINK_RF_EVENT_MASK); } if(EasyLink_CmdHandle_isValid(asyncCmdHndl)) { status = EasyLink_Status_Success; } else { status = EasyLink_Status_Cmd_Error; } } return status; } //*****************************************************************************// EasyLink_Status EasyLink_init(EasyLink_Params *params) { if (params == NULL) { EasyLink_Params_init(&EasyLink_params); } else { memcpy(&EasyLink_params, params, sizeof(EasyLink_params)); } if (configured) { //Already configure, check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } RF_close(rfHandle); } if (!rfParamsConfigured) { RF_Params_init(&rfParams); //set default InactivityTimeout to 1000us rfParams.nInactivityTimeout = inactivityTimeout; //configure event callback if(EasyLink_params.pClientEventCb != NULL && EasyLink_params.nClientEventMask != 0){ rfParams.pClientEventCb = EasyLink_params.pClientEventCb; rfParams.nClientEventMask = EasyLink_params.nClientEventMask; } rfParams.nID = RF_STACK_ID_EASYLINK; rfParamsConfigured = 1; // Initialize the schedule parameters RF_ScheduleCmdParams_init(&schParams_prop); } // Assign the random number generator function pointer to the global // handle, if it is NULL any function that employs it will return a // configuration error getRN = EasyLink_params.pGrnFxn; // Configure the EasyLink Carrier Sense Command memset(&EasyLink_cmdPropCs, 0, sizeof(rfc_CMD_PROP_CS_t)); EasyLink_cmdPropCs.commandNo = CMD_PROP_CS; EasyLink_cmdPropCs.rssiThr = EASYLINK_CS_RSSI_THRESHOLD_DBM; EasyLink_cmdPropCs.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropCs.condition.rule = COND_STOP_ON_TRUE; // Stop next command if this command returned TRUE, // End causes for the CMD_PROP_CS command: // Observed channel state Busy with csConf.busyOp = 1: PROP_DONE_BUSY TRUE // 0bserved channel state Idle with csConf.idleOp = 1: PROP_DONE_IDLE FALSE // Timeout trigger observed with channel state Busy: PROP_DONE_BUSY TRUE // Timeout trigger observed with channel state Idle: PROP_DONE_IDLE FALSE // Timeout trigger observed with channel state Invalid and csConf.timeoutRes = 0: PROP_DONE_BUSYTIMEOUT TRUE // Timeout trigger observed with channel state Invalid and csConf.timeoutRes = 1: PROP_DONE_IDLETIMEOUT FALSE // Received CMD_STOP after command started: PROP_DONE_STOPPED FALSE EasyLink_cmdPropCs.csConf.bEnaRssi = 0x1; // Enable RSSI as a criterion EasyLink_cmdPropCs.csConf.busyOp = 0x1; // End carrier sense on channel Busy EasyLink_cmdPropCs.csConf.idleOp = 0x0; // Continue carrier sense on channel Idle EasyLink_cmdPropCs.csEndTrigger.triggerType = TRIG_REL_START; // Ends at a time relative to the command started EasyLink_cmdPropCs.csEndTime = EasyLink_us_To_RadioTime(EASYLINK_CHANNEL_IDLE_TIME_US); bool useDivRadioSetup = true; bool rfConfigOk = false; bool createCmdTxAdvFromTx = false; useIeeeHeader = false; // Check if the PHY setting is compatible with the current device switch(EasyLink_params.ui32ModType) { case EasyLink_Phy_Custom: if((ChipInfo_ChipFamilyIs_CC26x0()) || (ChipInfo_ChipFamilyIs_CC26x0R2())) { useDivRadioSetup= false; } rfConfigOk = true; break; case EasyLink_Phy_50kbps2gfsk: if(!(ChipInfo_ChipFamilyIs_CC26x0()) && !(ChipInfo_ChipFamilyIs_CC26x0R2())) { useDivRadioSetup= true; rfConfigOk = true; } break; case EasyLink_Phy_625bpsLrm: if(!(ChipInfo_ChipFamilyIs_CC26x0()) && !(ChipInfo_ChipFamilyIs_CC26x0R2()) && !(ChipInfo_ChipFamilyIs_CC13x2_CC26x2()) && !(ChipInfo_ChipFamilyIs_CC13x2x7_CC26x2x7())) { useDivRadioSetup= true; rfConfigOk = true; } break; case EasyLink_Phy_2_4_100kbps2gfsk: if((ChipInfo_GetChipType() == CHIP_TYPE_CC2640R2)) { useDivRadioSetup= false; rfConfigOk = true; } else if((ChipInfo_ChipFamilyIs_CC13x2_CC26x2()) && (ChipInfo_GetChipType() != CHIP_TYPE_CC1312)) { useDivRadioSetup= true; rfConfigOk = true; } else if((ChipInfo_ChipFamilyIs_CC13x2x7_CC26x2x7()) && (ChipInfo_GetChipType() != CHIP_TYPE_CC1312R7)) { useDivRadioSetup= true; rfConfigOk = true; } break; case EasyLink_Phy_2_4_200kbps2gfsk: if((ChipInfo_GetChipType() == CHIP_TYPE_CC2650)) { useDivRadioSetup= false; rfConfigOk = true; } break; case EasyLink_Phy_2_4_250kbps2gfsk: if((ChipInfo_GetChipType() == CHIP_TYPE_CC2640R2)) { useDivRadioSetup= false; rfConfigOk = true; } else if((ChipInfo_ChipFamilyIs_CC13x2_CC26x2()) && (ChipInfo_GetChipType() != CHIP_TYPE_CC1312)) { useDivRadioSetup= true; rfConfigOk = true; } else if((ChipInfo_ChipFamilyIs_CC13x2x7_CC26x2x7()) && (ChipInfo_GetChipType() != CHIP_TYPE_CC1312R7)) { useDivRadioSetup= true; rfConfigOk = true; } break; case EasyLink_Phy_5kbpsSlLr: if(!(ChipInfo_ChipFamilyIs_CC26x0()) && !(ChipInfo_ChipFamilyIs_CC26x0R2())) { useDivRadioSetup= true; rfConfigOk = true; } break; case EasyLink_Phy_200kbps2gfsk: if((ChipInfo_GetChipType() == CHIP_TYPE_CC1312) || (ChipInfo_GetChipType() == CHIP_TYPE_CC1352) || (ChipInfo_GetChipType() == CHIP_TYPE_CC1352P) || (ChipInfo_GetChipType() == CHIP_TYPE_CC1312R7)) { #if !defined(LAUNCHXL_CC1352P_4) && !defined(LP_CC1352P7_4) // This mode is not supported in the 433 MHz band useDivRadioSetup= true; rfConfigOk = true; #endif } break; default: // Invalid PHY setting rfConfigOk = false; break; } // Return an error if the PHY setting is incompatible with the current device if(!rfConfigOk) { if (busyMutex != NULL) { Semaphore_post(busyMutex); } return EasyLink_Status_Param_Error; } // Loop through the EasyLink_supportedPhys array looking for the PHY uint8_t i = 0; while(i < EasyLink_numSupportedPhys) { if(EasyLink_supportedPhys[i].EasyLink_phyType == EasyLink_params.ui32ModType) { rfSetting = &EasyLink_supportedPhys[i]; if(EasyLink_supportedPhys[i].RF_pCmdPropTxAdv == NULL) { // Advanced Tx command was not generated, create one from the // base Tx command. IEEE header is not used by default createCmdTxAdvFromTx = true; } else { // Advanced Tx command was generated, an IEEE header is // required for this PHY useIeeeHeader = true; } break; } i++; } // Return an error if the PHY isn't in the supported settings list if(rfSetting == 0) { if (busyMutex != NULL) { Semaphore_post(busyMutex); } return EasyLink_Status_Param_Error; } // Copy the PHY settings to the EasyLink PHY variable if(useDivRadioSetup) { #if ((defined LAUNCHXL_CC1352P1) || (defined LAUNCHXL_CC1352P_2) || \ (defined LAUNCHXL_CC1352P_4)|| (defined LP_CC1352P7_1) || \ (defined LP_CC1352P7_4) || (defined CONFIG_LP_CC2652PSIP) || \ (defined CONFIG_CC2652P1FSIP)) memcpy(&EasyLink_cmdPropRadioSetup.divSetup, (rfSetting->RF_uCmdPropRadio.RF_pCmdPropRadioDivSetup), sizeof(rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t)); #else memcpy(&EasyLink_cmdPropRadioSetup.divSetup, (rfSetting->RF_uCmdPropRadio.RF_pCmdPropRadioDivSetup), sizeof(rfc_CMD_PROP_RADIO_DIV_SETUP_t)); #endif } else { memcpy(&EasyLink_cmdPropRadioSetup.setup, (rfSetting->RF_uCmdPropRadio.RF_pCmdPropRadioSetup), sizeof(rfc_CMD_PROP_RADIO_SETUP_t)); } memcpy(&EasyLink_cmdFs, (rfSetting->RF_pCmdFs), sizeof(rfc_CMD_FS_t)); memcpy(&EasyLink_RF_prop, (rfSetting->RF_pProp), sizeof(RF_Mode)); memcpy(&EasyLink_cmdPropRxAdv,(rfSetting->RF_pCmdPropRxAdv), sizeof(rfc_CMD_PROP_RX_ADV_t)); if(createCmdTxAdvFromTx) { createTxAdvFromTx(&EasyLink_cmdPropTxAdv, (rfSetting->RF_pCmdPropTx)); } else { memcpy(&EasyLink_cmdPropTxAdv, (rfSetting->RF_pCmdPropTxAdv), sizeof(rfc_CMD_PROP_TX_ADV_t)); } #if !(defined(DeviceFamily_CC26X0R2)) if (rfModeMultiClient) { EasyLink_RF_prop.rfMode = RF_MODE_MULTIPLE; } #endif //defined(DeviceFamily_CC26X0R2) /* Request access to the radio */ rfHandle = RF_open(&rfObject, &EasyLink_RF_prop, (RF_RadioSetup*)&EasyLink_cmdPropRadioSetup.setup, &rfParams); // Setup the Proprietary Rx Advanced Command EasyLink_cmdPropRxAdv.status = 0x0000; EasyLink_cmdPropRxAdv.pNextOp = 0; EasyLink_cmdPropRxAdv.startTime = 0x00000000; EasyLink_cmdPropRxAdv.startTrigger.triggerType = 0x0; EasyLink_cmdPropRxAdv.startTrigger.bEnaCmd = 0x0; EasyLink_cmdPropRxAdv.startTrigger.triggerNo = 0x0; EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 0x0; EasyLink_cmdPropRxAdv.condition.rule = 0x1; EasyLink_cmdPropRxAdv.condition.nSkip = 0x0; EasyLink_cmdPropRxAdv.pktConf.bFsOff = 0x0; EasyLink_cmdPropRxAdv.pktConf.bRepeatOk = 0x0; EasyLink_cmdPropRxAdv.pktConf.bRepeatNok = 0x0; EasyLink_cmdPropRxAdv.pktConf.bUseCrc = 0x1; EasyLink_cmdPropRxAdv.pktConf.bCrcIncSw = 0x0; EasyLink_cmdPropRxAdv.pktConf.endType = 0x0; EasyLink_cmdPropRxAdv.pktConf.filterOp = !(EASYLINK_ENABLE_ADDR_FILTERING); EasyLink_cmdPropRxAdv.rxConf.bAutoFlushIgnored = 0x0; EasyLink_cmdPropRxAdv.rxConf.bAutoFlushCrcErr = 0x0; EasyLink_cmdPropRxAdv.rxConf.bIncludeHdr = 0x1; EasyLink_cmdPropRxAdv.rxConf.bIncludeCrc = 0x0; EasyLink_cmdPropRxAdv.rxConf.bAppendRssi = 0x0; EasyLink_cmdPropRxAdv.rxConf.bAppendTimestamp = 0x0; EasyLink_cmdPropRxAdv.rxConf.bAppendStatus = 0x0; EasyLink_cmdPropRxAdv.syncWord1 = 0; EasyLink_cmdPropRxAdv.maxPktLen = EASYLINK_MAX_DATA_LENGTH + EASYLINK_MAX_ADDR_SIZE; if(useIeeeHeader) { EasyLink_cmdPropRxAdv.syncWord0 = EASYLINK_IEEE_TRX_SYNC_WORD; EasyLink_cmdPropRxAdv.hdrConf.numHdrBits = EASYLINK_IEEE_HDR_NBITS; EasyLink_cmdPropRxAdv.lenOffset = EASYLINK_IEEE_LEN_OFFSET; // Exclude the header from the CRC calculation EasyLink_cmdPropRxAdv.pktConf.bCrcIncHdr = 0U; } else { EasyLink_cmdPropRxAdv.syncWord0 = EASYLINK_PROP_TRX_SYNC_WORD; EasyLink_cmdPropRxAdv.hdrConf.numHdrBits = EASYLINK_PROP_HDR_NBITS; EasyLink_cmdPropRxAdv.lenOffset = EASYLINK_PROP_LEN_OFFSET; // Include the header in the CRC calculation - The header (length // byte) is considered to be the first byte of the payload EasyLink_cmdPropRxAdv.pktConf.bCrcIncHdr = 1U; } EasyLink_cmdPropRxAdv.hdrConf.numLenBits = EASYLINK_HDR_LEN_NBITS; EasyLink_cmdPropRxAdv.hdrConf.lenPos = 0; EasyLink_cmdPropRxAdv.addrConf.addrType = 0; EasyLink_cmdPropRxAdv.addrConf.addrSize = addrSize; EasyLink_cmdPropRxAdv.addrConf.addrPos = 0; EasyLink_cmdPropRxAdv.addrConf.numAddr = EASYLINK_NUM_ADDR_FILTER; EasyLink_cmdPropRxAdv.endTrigger.triggerType = 0x1; EasyLink_cmdPropRxAdv.endTrigger.bEnaCmd = 0x0; EasyLink_cmdPropRxAdv.endTrigger.triggerNo = 0x0; EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 0x0; EasyLink_cmdPropRxAdv.endTime = 0x00000000; EasyLink_cmdPropRxAdv.pAddr = addrFilterTable; EasyLink_cmdPropRxAdv.pQueue = &dataQueue; EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics; if (rfModeMultiClient) { /* Set params */ schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); //Set the frequency (void)RF_runScheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdFs, &schParams_prop, 0, //asyncCmdCallback, EASYLINK_RF_EVENT_MASK); } else { //Set the frequency (void)RF_runCmd(rfHandle, (RF_Op*)&EasyLink_cmdFs, RF_PriorityNormal, 0, //asyncCmdCallback, EASYLINK_RF_EVENT_MASK); } //Create a semaphore for blocking commands Semaphore_Params semParams; Error_Block eb; // init params Semaphore_Params_init(&semParams); Error_init(&eb); // create semaphore instance if not already created if (busyMutex == NULL) { busyMutex = Semaphore_create(0, &semParams, &eb); if (busyMutex == NULL) { return EasyLink_Status_Mem_Error; } Semaphore_post(busyMutex); } else { //already configured and taken busyMutex, so release it Semaphore_post(busyMutex); } configured = 1; return EasyLink_Status_Success; } //*****************************************************************************// EasyLink_Status EasyLink_setFrequency_SET(uint32_t ui32Frequency) { EasyLink_Status status = EasyLink_Status_Cmd_Error; uint16_t centerFreq, fractFreq; uint32_t Freq; Freq=2402*10000+ui32Frequency*20000; if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } /* Set the frequency */ centerFreq = (uint16_t)(Freq / 1000000); fractFreq = (uint16_t) (((uint64_t)Freq - ((uint64_t)centerFreq * 1000000)) * 65536 / 1000000); EasyLink_cmdFs.frequency = centerFreq; EasyLink_cmdFs.fractFreq = fractFreq; /* Set params */ schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); #if (!defined(DeviceFamily_CC26X0R2) && !defined(DeviceFamily_CC26X0)) /* If the command type is CMD_PROP_RADIO_DIV_SETUP then set the center frequency * to the same band as the FS command */ if((EasyLink_cmdPropRadioSetup.divSetup.commandNo == CMD_PROP_RADIO_DIV_SETUP) && (EasyLink_cmdPropRadioSetup.divSetup.centerFreq != centerFreq)) { EasyLink_cmdPropRadioSetup.divSetup.centerFreq = centerFreq; if (rfModeMultiClient) { /* Run the Setup Command */ (void)RF_runScheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRadioSetup, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { /* Run the Setup Command */ (void)RF_runCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRadioSetup, RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK); } } #endif RF_EventMask result; if (rfModeMultiClient) { /* Run command */ result = RF_runScheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdFs, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { /* Run command */ result = RF_runCmd(rfHandle, (RF_Op*)&EasyLink_cmdFs, RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK); } if((result & RF_EventLastCmdDone) && (EasyLink_cmdFs.status == DONE_OK)) { status = EasyLink_Status_Success; } Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_setFrequency(uint32_t ui32Frequency) { EasyLink_Status status = EasyLink_Status_Cmd_Error; uint16_t centerFreq, fractFreq; if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } /* Set the frequency */ centerFreq = (uint16_t)(ui32Frequency / 1000000); fractFreq = (uint16_t) (((uint64_t)ui32Frequency - ((uint64_t)centerFreq * 1000000)) * 65536 / 1000000); EasyLink_cmdFs.frequency = centerFreq; EasyLink_cmdFs.fractFreq = fractFreq; /* Set params */ schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); #if (!defined(DeviceFamily_CC26X0R2) && !defined(DeviceFamily_CC26X0)) /* If the command type is CMD_PROP_RADIO_DIV_SETUP then set the center frequency * to the same band as the FS command */ if((EasyLink_cmdPropRadioSetup.divSetup.commandNo == CMD_PROP_RADIO_DIV_SETUP) && (EasyLink_cmdPropRadioSetup.divSetup.centerFreq != centerFreq)) { EasyLink_cmdPropRadioSetup.divSetup.centerFreq = centerFreq; if (rfModeMultiClient) { /* Run the Setup Command */ (void)RF_runScheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRadioSetup, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { /* Run the Setup Command */ (void)RF_runCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRadioSetup, RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK); } } #endif RF_EventMask result; if (rfModeMultiClient) { /* Run command */ result = RF_runScheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdFs, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { /* Run command */ result = RF_runCmd(rfHandle, (RF_Op*)&EasyLink_cmdFs, RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK); } if((result & RF_EventLastCmdDone) && (EasyLink_cmdFs.status == DONE_OK)) { status = EasyLink_Status_Success; } Semaphore_post(busyMutex); return status; } //*****************************************************************************// uint32_t EasyLink_getFrequency(void) { uint32_t freq_khz; if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } freq_khz = EasyLink_cmdFs.frequency * 1000000; freq_khz += ((((uint64_t)EasyLink_cmdFs.fractFreq * 1000000)) / 65536); return freq_khz; } //*****************************************************************************// EasyLink_Status EasyLink_setRfPower(int8_t i8TxPowerDbm) { EasyLink_Status status = EasyLink_Status_Cmd_Error; if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } #if (defined CONFIG_CC1352R1F3RGZ) || (defined CONFIG_CC1312R1F3RGZ) || \ (defined CONFIG_CC2652R1FRGZ) || (defined CONFIG_CC2652R1FSIP) || \ (defined CONFIG_CC2652P1FSIP) || (defined CONFIG_CC2652R7RGZ) || \ (defined CONFIG_CC1312R7RGZ) || (defined CONFIG_CC1352P7RGZ) || \ (defined CONFIG_CC1312R1_LAUNCHXL) || (defined CONFIG_CC1352R1_LAUNCHXL) || \ (defined LAUNCHXL_CC1352P1) || (defined CONFIG_CC26X2R1_LAUNCHXL) || \ (defined LAUNCHXL_CC1352P_4) || (defined LAUNCHXL_CC1352P_2) || \ (defined CONFIG_LP_CC2652PSIP) || (defined CONFIG_LP_CC2652RSIP) || \ (defined CONFIG_LP_CC1312R7) || (defined LP_CC1352P7_4) || \ (defined LP_CC1352P7_1) || (defined CONFIG_LP_CC2652R7) RF_TxPowerTable_Entry *rfPowerTable = NULL; RF_TxPowerTable_Value newValue; uint8_t rfPowerTableSize = 0; newValue = RF_TxPowerTable_findValue((RF_TxPowerTable_Entry *)rfSetting->RF_pTxPowerTable, i8TxPowerDbm); if(newValue.rawValue != RF_TxPowerTable_INVALID_VALUE) { // Found a valid entry rfPowerTable = (RF_TxPowerTable_Entry *)rfSetting->RF_pTxPowerTable; rfPowerTableSize = rfSetting->RF_txPowerTableSize; } else { //Release the busyMutex Semaphore_post(busyMutex); // Desired power is too low to be supported on this device return EasyLink_Status_Config_Error; } //if max power is requested then the CCFG_FORCE_VDDR_HH must be set in //the ccfg; this does not apply to 2.4GHz proprietary modes #if (CCFG_FORCE_VDDR_HH != 0x1) if((newValue.paType == RF_TxPowerTable_DefaultPA) && (i8TxPowerDbm == rfPowerTable[rfPowerTableSize-2].power) && (EasyLink_params.ui32ModType != EasyLink_Phy_2_4_100kbps2gfsk) && (EasyLink_params.ui32ModType != EasyLink_Phy_2_4_250kbps2gfsk)) { //Release the busyMutex Semaphore_post(busyMutex); // The desired power level is set to the maximum supported under the // default PA settings, but the boost mode (CCFG_FORCE_VDDR_HH) is not // turned on return EasyLink_Status_Config_Error; } #else // dummy read to avoid build warnings if(rfPowerTable[rfPowerTableSize-2].power){} #endif RF_Stat rfStatus = RF_setTxPower(rfHandle, newValue); if(rfStatus == RF_StatSuccess) { status = EasyLink_Status_Success; } else { status = EasyLink_Status_Config_Error; } #else rfc_CMD_SCH_IMM_t immOpCmd = {0}; rfc_CMD_SET_TX_POWER_t cmdSetPower = {0}; uint8_t txPowerIdx; immOpCmd.commandNo = CMD_SCH_IMM; immOpCmd.startTrigger.triggerType = TRIG_NOW; immOpCmd.startTrigger.pastTrig = 1; immOpCmd.startTime = 0; cmdSetPower.commandNo = CMD_SET_TX_POWER; if (i8TxPowerDbm < rfPowerTable[0].dbm) { i8TxPowerDbm = rfPowerTable[0].dbm; } else if (i8TxPowerDbm > rfPowerTable[rfPowerTableSize-1].dbm ) { i8TxPowerDbm = rfPowerTable[rfPowerTableSize-1].dbm; } //if max power is requested then the CCFG_FORCE_VDDR_HH must be set in //the ccfg #if (CCFG_FORCE_VDDR_HH != 0x1) if (i8TxPowerDbm == rfPowerTable[rfPowerTableSize-1].dbm) { //Release the busyMutex Semaphore_post(busyMutex); return EasyLink_Status_Config_Error; } #endif for (txPowerIdx = 0; txPowerIdx < rfPowerTableSize; txPowerIdx++) { if (i8TxPowerDbm >= rfPowerTable[txPowerIdx].dbm) { cmdSetPower.txPower = rfPowerTable[txPowerIdx].txPower; EasyLink_cmdPropRadioSetup.setup.txPower = rfPowerTable[txPowerIdx].txPower; } } //point the Operational Command to the immediate set power command immOpCmd.cmdrVal = (uint32_t) &cmdSetPower; // Send command RF_CmdHandle cmd = RF_postCmd(rfHandle, (RF_Op*)&immOpCmd, RF_PriorityNormal, 0, EASYLINK_RF_EVENT_MASK); RF_EventMask result = RF_pendCmd(rfHandle, cmd, RF_EventLastCmdDone); if (result & RF_EventLastCmdDone) { status = EasyLink_Status_Success; } #endif //Release the busyMutex Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_getRfPower(int8_t *pi8TxPowerDbm) { int8_t txPowerDbm = 0xff; if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } #if (defined CONFIG_CC1352R1F3RGZ) || (defined CONFIG_CC1312R1F3RGZ) || \ (defined CONFIG_CC2652R1FRGZ) || (defined CONFIG_CC2652R1FSIP) || \ (defined CONFIG_CC2652P1FSIP) || (defined CONFIG_CC1312R7RGZ) || \ (defined CONFIG_CC1352P7RGZ) || (defined CONFIG_CC2652R7RGZ) || \ (defined CONFIG_CC1312R1_LAUNCHXL) || (defined CONFIG_CC1352R1_LAUNCHXL) || \ (defined LAUNCHXL_CC1352P1) || (defined CONFIG_CC26X2R1_LAUNCHXL) || \ (defined LAUNCHXL_CC1352P_4) || (defined LAUNCHXL_CC1352P_2) || \ (defined CONFIG_LP_CC2652PSIP) || (defined CONFIG_LP_CC2652RSIP) || \ (defined CONFIG_LP_CC1312R7) || (defined LP_CC1352P7_4) || \ (defined LP_CC1352P7_1) || (defined CONFIG_LP_CC2652R7) uint8_t rfPowerTableSize = 0; RF_TxPowerTable_Entry *rfPowerTable = NULL; RF_TxPowerTable_Value currValue = RF_getTxPower(rfHandle); if(currValue.rawValue == RF_TxPowerTable_INVALID_VALUE) { // Value not valid return EasyLink_Status_Config_Error; } else { rfPowerTable = (RF_TxPowerTable_Entry *)rfSetting->RF_pTxPowerTable; rfPowerTableSize = rfSetting->RF_txPowerTableSize; txPowerDbm = RF_TxPowerTable_findPowerLevel(rfPowerTable, currValue); //if CCFG_FORCE_VDDR_HH is not set max power cannot be achieved; this //does not apply to 2.4GHz proprietary modes #if (CCFG_FORCE_VDDR_HH != 0x1) if((currValue.paType == RF_TxPowerTable_DefaultPA) && (txPowerDbm == rfPowerTable[rfPowerTableSize-2].power) && (EasyLink_params.ui32ModType != EasyLink_Phy_2_4_100kbps2gfsk) && (EasyLink_params.ui32ModType != EasyLink_Phy_2_4_250kbps2gfsk)) { txPowerDbm = rfPowerTable[rfPowerTableSize-3].power; } #else // dummy read to avoid build warnings if(rfPowerTable[rfPowerTableSize-2].power){} #endif } #else uint8_t txPowerIdx; for (txPowerIdx = 0; txPowerIdx < rfPowerTableSize; txPowerIdx++) { if (rfPowerTable[txPowerIdx].txPower == EasyLink_cmdPropRadioSetup.setup.txPower) { txPowerDbm = rfPowerTable[txPowerIdx].dbm; continue; } } //if CCFG_FORCE_VDDR_HH is not set max power cannot be achieved #if (CCFG_FORCE_VDDR_HH != 0x1) if (txPowerDbm == rfPowerTable[rfPowerTableSize-1].dbm) { txPowerDbm = rfPowerTable[rfPowerTableSize-2].dbm; } #endif #endif *pi8TxPowerDbm = txPowerDbm; return EasyLink_Status_Success; } //*****************************************************************************// EasyLink_Status EasyLink_getRssi(int8_t *pi8Rssi) { if((!configured) || suspended) { return EasyLink_Status_Config_Error; } *pi8Rssi = RF_getRssi(rfHandle); return EasyLink_Status_Success; } //*****************************************************************************// EasyLink_Status EasyLink_getAbsTime(uint32_t *pui32AbsTime) { if((!configured) || suspended) { return EasyLink_Status_Config_Error; } *pui32AbsTime = RF_getCurrentTime(); return EasyLink_Status_Success; } //*****************************************************************************// EasyLink_Status EasyLink_transmit_DBeacon(EasyLink_DBeacon *txPacket,EasyLink_TimeStamp TimeStamp) { EasyLink_Status status = EasyLink_Status_Tx_Error; RF_CmdHandle cmdHdl; uint32_t cmdTime; unsigned char bitArray[13] = {0}; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); /*****************************************/ bitArray[12]|=txPacket->fDBeacon.Reserved&0x03; //Make any bit 2 Reserved bitArray[12]|=(txPacket->fDBeacon.ChannelNumber&0x3f)<<2; //Make any bit 6 ChannelNumber bitArray[11]|=txPacket->fDBeacon.ChangeTiming; //Make any bit 8 ChangeTiming bitArray[10]|=txPacket->fDBeacon.SlotReassignmentTimung; //Make any bit 8 SlotReassignment bitArray[9]|=txPacket->fDBeacon.DSRList; //Make any bit 16 DSRList bitArray[8]|=txPacket->fDBeacon.DSRList>>8; bitArray[7]|=txPacket->fDBeacon.TimeStamp; //Make any bit 24 TimeStamp bitArray[6]|=txPacket->fDBeacon.TimeStamp>>8; bitArray[5]|=txPacket->fDBeacon.TimeStamp>>16; bitArray[4]|=txPacket->fDBeacon.MultiuseAccess&0x01; //Make any bit 1 MultiuseAccess bitArray[4]|=(txPacket->fDBeacon.ChannelMigration&0x01)<<1; //Make any bit 1 ChannelMigration bitArray[4]|=(txPacket->fDBeacon.SlotReassignment&0x01)<<2; //Make any bit 1 SlitRessignment bitArray[4]|=(txPacket->fDBeacon.DownlinkData&0x01)<<3; //Make any bit 1 DownlinkData bitArray[4]|=txPacket->fDBeacon.InactiveStartSlot<<4; //Make any bit 8 InactiveStartSlot bitArray[3]|=txPacket->fDBeacon.InactiveStartSlot>>4; bitArray[3]|=txPacket->fDBeacon.CMStartSlot<<4; //Make any bit 10 CMStartSlot bitArray[2]|=txPacket->fDBeacon.CMStartSlot>>4; bitArray[2]|=txPacket->fDBeacon.IBI_Totalslots<<6; //Make any bit 10 IBI_Totalslots bitArray[1]|=txPacket->fDBeacon.IBI_Totalslots>>2; bitArray[0]|=txPacket->fDBeacon.HubAddr; //Make any bit 8 HubAddr /*****************************************/ usprintf_mng("TransDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", bitArray[0],bitArray[1],bitArray[2],bitArray[3],bitArray[4],bitArray[5],bitArray[6],bitArray[7],bitArray[8],bitArray[9],bitArray[10],bitArray[11],bitArray[12]); if ( (!configured) || suspended) {return EasyLink_Status_Config_Error;} if (txPacket->len > EASYLINK_MAX_DATA_LENGTH) {return EasyLink_Status_Param_Error;} if (Semaphore_pend(busyMutex, 0) == false) //Check and take the busyMutex {return EasyLink_Status_Busy_Error;} //if(useIeeeHeader) //Use an IEEE header for the Tx/Rx command //uint16_t ieeeHdr = EASYLINK_IEEE_HDR_CREATE(EASYLINK_IEEE_HDR_CRC_2BYTE, EASYLINK_IEEE_HDR_WHTNG_EN, (txPacket->len + addrSize + sizeof(ieeeHdr))); //hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); //txBuffer[0] = (uint8_t)(ieeeHdr & 0x00FF); //txBuffer[1] = (uint8_t)((ieeeHdr & 0xFF00) >> 8); //hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); //txBuffer[0] = txPacket->len + addrSize; //EASYLINK_USE_DEFAULT_ADDR //memcpy(&txBuffer[hdrSize], defaultAddr, addrSize); // Use the default address defined in easylink_config.h //memcpy(&txBuffer[hdrSize], txPacket->dstAddr, addrSize); // Use the address passed in from the application //memcpy(&txBuffer[addrSize + hdrSize], txPacket->payload, txPacket->len); //EasyLink_cmdPropTxAdv.pktLen = txPacket->len + addrSize + hdrSize; //packet length to Tx includes address and length field //EasyLink_cmdPropTxAdv.pPkt = txBuffer; EasyLink_cmdPropTxAdv.pktLen = sizeof(bitArray); EasyLink_cmdPropTxAdv.pPkt = bitArray; //EasyLink_params.ui32ModType == EasyLink_Phy_5kbpsSlLr //cmdTime = (EasyLink_cmdPropTxAdv.pktLen*PKT_NCHIPS_SLR_5K + PKT_OVHD_SLR_5K) / BAUD_RATE_SLR_5K; //EasyLink_params.ui32ModType == EasyLink_Phy_200kbps2gfsk //cmdTime = ((EasyLink_cmdPropTxAdv.pktLen + PKT_OVHD_2GFSK_200K) * CHAR_BIT) / BAUD_RATE_2GFSK_200K; //assume 50kbps cmdTime = ((EasyLink_cmdPropTxAdv.pktLen + PKT_OVHD_2GFSK_50K) * CHAR_BIT) / BAUD_RATE_2GFSK_50K; //cmdTime = calculateCmdTime(&txPacket); //txPacket->absTime != 0 //EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_ABSTIME; //EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropTxAdv.startTime = txPacket->absTime; //schParams_prop.startTime = txPacket->absTime; //schParams_prop.startType = RF_StartAbs; //schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endTime = EasyLink_cmdPropTxAdv.startTime + EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endType = RF_EndAbs; //else //EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW; //EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropTxAdv.startTime = 0U; //schParams_prop.startTime = 0U; //schParams_prop.startType = RF_StartNotSpecified; //schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endTime = RF_getCurrentTime() + EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endType = RF_EndAbs; EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropTxAdv.startTime = TimeStamp.StartTime; schParams_prop.startTime = TimeStamp.StartTime; schParams_prop.startType = RF_StartAbs; schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endTime = EasyLink_cmdPropTxAdv.startTime + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; if(rfModeMultiClient) // Send packet { cmdHdl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { cmdHdl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv,RF_PriorityHigh, 0, EASYLINK_RF_EVENT_MASK); } RF_EventMask result = RF_pendCmd(rfHandle, cmdHdl, EASYLINK_RF_EVENT_MASK); // Wait for Command to complete if (result == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else if (result & RF_EventLastCmdDone) { status = EasyLink_Status_Success; } //Release the busyMutex Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_transmit_CBeacon(EasyLink_CBeacon *txPacket,EasyLink_TimeStamp TimeStamp) { EasyLink_Status status = EasyLink_Status_Tx_Error; RF_CmdHandle cmdHdl; uint32_t cmdTime; unsigned char bitArray[13] = {0}; /*****************************************/ bitArray[7]|=txPacket->fCBeacon.TimeStamp; //Make any bit 32 TimeStamp bitArray[6]|=txPacket->fCBeacon.TimeStamp>>8; bitArray[5]|=txPacket->fCBeacon.TimeStamp>>16; bitArray[4]|=txPacket->fCBeacon.TimeStamp>>24; bitArray[3]|=txPacket->fCBeacon.InitialState; //Make any bit 1 InitialState bitArray[3]|=txPacket->fCBeacon.DCHChannelNum<<1; //Make any bit 6 DCHChannelNum bitArray[3]|=txPacket->fCBeacon.DutyCycling<<7; //Make any bit 2 DutyCycling bitArray[2]|=txPacket->fCBeacon.DutyCycling>>1; bitArray[2]|=txPacket->fCBeacon.InterferenceMitigation<<1; //Make any bit 1 InterferenceMitigation bitArray[2]|=txPacket->fCBeacon.Reser_1<<2; //Make any bit 1 Reserved bitArray[2]|=txPacket->fCBeacon.TimeSlots<<3; //Make any bit 10 TimeSlots bitArray[1]|=txPacket->fCBeacon.TimeSlots>>5; bitArray[1]|=txPacket->fCBeacon.SlotLen<<5; //Make any bit 3 SlotLen bitArray[0]|=txPacket->fCBeacon.HubAddr; //Make any bit 8 HubAddr /*****************************************/ usprintf_mng("TransCB:%02x %02x %02x %02x %02x %02x %02x %02x\n", bitArray[0],bitArray[1],bitArray[2],bitArray[3],bitArray[4],bitArray[5],bitArray[6],bitArray[7]); schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); if ( (!configured) || suspended) {return EasyLink_Status_Config_Error;} if (txPacket->len > EASYLINK_MAX_DATA_LENGTH) {return EasyLink_Status_Param_Error;} if (Semaphore_pend(busyMutex, 0) == false) //Check and take the busyMutex {return EasyLink_Status_Busy_Error;} //if(useIeeeHeader) //Use an IEEE header for the Tx/Rx command //uint16_t ieeeHdr = EASYLINK_IEEE_HDR_CREATE(EASYLINK_IEEE_HDR_CRC_2BYTE, EASYLINK_IEEE_HDR_WHTNG_EN, (txPacket->len + addrSize + sizeof(ieeeHdr))); //hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); //txBuffer[0] = (uint8_t)(ieeeHdr & 0x00FF); //txBuffer[1] = (uint8_t)((ieeeHdr & 0xFF00) >> 8); //hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); //txBuffer[0] = txPacket->len + addrSize; //EASYLINK_USE_DEFAULT_ADDR //memcpy(&txBuffer[hdrSize], defaultAddr, addrSize); // Use the default address defined in easylink_config.h //memcpy(&txBuffer[hdrSize], txPacket->dstAddr, addrSize); // Use the address passed in from the application //memcpy(&txBuffer[addrSize + hdrSize], txPacket->payload, txPacket->len); //EasyLink_cmdPropTxAdv.pktLen = txPacket->len + addrSize + hdrSize; //packet length to Tx includes address and length field //EasyLink_cmdPropTxAdv.pPkt = txBuffer; EasyLink_cmdPropTxAdv.pktLen = sizeof(bitArray); EasyLink_cmdPropTxAdv.pPkt = bitArray; //EasyLink_params.ui32ModType == EasyLink_Phy_5kbpsSlLr //cmdTime = (EasyLink_cmdPropTxAdv.pktLen*PKT_NCHIPS_SLR_5K + PKT_OVHD_SLR_5K) / BAUD_RATE_SLR_5K; //EasyLink_params.ui32ModType == EasyLink_Phy_200kbps2gfsk //cmdTime = ((EasyLink_cmdPropTxAdv.pktLen + PKT_OVHD_2GFSK_200K) * CHAR_BIT) / BAUD_RATE_2GFSK_200K; //assume 50kbps cmdTime = ((EasyLink_cmdPropTxAdv.pktLen + PKT_OVHD_2GFSK_50K) * CHAR_BIT) / BAUD_RATE_2GFSK_50K; //cmdTime = calculateCmdTime(&txPacket); //txPacket->absTime != 0 //EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_ABSTIME; //EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropTxAdv.startTime = txPacket->absTime; //schParams_prop.startTime = txPacket->absTime; //schParams_prop.startType = RF_StartAbs; //schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endTime = EasyLink_cmdPropTxAdv.startTime + EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endType = RF_EndAbs; //else //EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW; //EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropTxAdv.startTime = 0U; //schParams_prop.startTime = 0U; //schParams_prop.startType = RF_StartNotSpecified; //schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endTime = RF_getCurrentTime() + EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endType = RF_EndAbs; EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropTxAdv.startTime = TimeStamp.StartTime; schParams_prop.startTime = TimeStamp.StartTime; schParams_prop.startType = RF_StartAbs; schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endTime = EasyLink_cmdPropTxAdv.startTime + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; if(rfModeMultiClient) // Send packet { cmdHdl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { cmdHdl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv,RF_PriorityHigh, 0, EASYLINK_RF_EVENT_MASK); } RF_EventMask result = RF_pendCmd(rfHandle, cmdHdl, EASYLINK_RF_EVENT_MASK); // Wait for Command to complete if (result == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else if (result & RF_EventLastCmdDone) { status = EasyLink_Status_Success; } //Release the busyMutex Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_transmit_Ack(EasyLink_AckPacket *txPacket,EasyLink_TimeStamp TimeStamp) { EasyLink_Status status = EasyLink_Status_Tx_Error; RF_CmdHandle cmdHdl; // uint32_t cmdTime; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); if ( (!configured) || suspended) {return EasyLink_Status_Config_Error;} if (txPacket->len > EASYLINK_MAX_DATA_LENGTH) {return EasyLink_Status_Param_Error;} if (Semaphore_pend(busyMutex, 0) == false) //Check and take the busyMutex {return EasyLink_Status_Busy_Error;} if(useIeeeHeader) //Use an IEEE header for the Tx/Rx command { uint16_t ieeeHdr = EASYLINK_IEEE_HDR_CREATE(EASYLINK_IEEE_HDR_CRC_2BYTE, EASYLINK_IEEE_HDR_WHTNG_EN, (txPacket->len + addrSize + sizeof(ieeeHdr))); hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); txBuffer[0] = (uint8_t)(ieeeHdr & 0x00FF); txBuffer[1] = (uint8_t)((ieeeHdr & 0xFF00) >> 8); } else { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); txBuffer[0] = txPacket->len + addrSize; } //EASYLINK_USE_DEFAULT_ADDR //memcpy(&txBuffer[hdrSize], defaultAddr, addrSize); // Use the default address defined in easylink_config.h //memcpy(&txBuffer[hdrSize], txPacket->dstAddr, addrSize); // Use the address passed in from the application //memcpy(&txBuffer[addrSize + hdrSize], txPacket->payload, txPacket->len); EasyLink_cmdPropTxAdv.pktLen = txPacket->len + addrSize + hdrSize; //packet length to Tx includes address and length field EasyLink_cmdPropTxAdv.pPkt = txBuffer; //cmdTime = calculateCmdTime(txPacket); //txPacket->absTime != 0 //EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_ABSTIME; //EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropTxAdv.startTime = txPacket->absTime; //schParams_prop.startTime = txPacket->absTime; //schParams_prop.startType = RF_StartAbs; //schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endTime = EasyLink_cmdPropTxAdv.startTime + EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endType = RF_EndAbs; //else EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropTxAdv.startTime = 0U; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; //schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endTime = RF_getCurrentTime() + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; if(rfModeMultiClient) // Send packet { cmdHdl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { cmdHdl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv,RF_PriorityHigh, 0, EASYLINK_RF_EVENT_MASK); } RF_EventMask result = RF_pendCmd(rfHandle, cmdHdl, EASYLINK_RF_EVENT_MASK); // Wait for Command to complete if (result == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else if (result & RF_EventLastCmdDone) { status = EasyLink_Status_Success; } //Release the busyMutex Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_transmit_CAss(EasyLink_CAss *txPacket,EasyLink_TimeStamp TimeStamp) { EasyLink_Status status = EasyLink_Status_Tx_Error; RF_CmdHandle cmdHdl; //uint32_t cmdTime; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); if ( (!configured) || suspended) {return EasyLink_Status_Config_Error;} if (txPacket->len > EASYLINK_MAX_DATA_LENGTH) {return EasyLink_Status_Param_Error;} if (Semaphore_pend(busyMutex, 0) == false) //Check and take the busyMutex {return EasyLink_Status_Busy_Error;} if(useIeeeHeader) //Use an IEEE header for the Tx/Rx command { uint16_t ieeeHdr = EASYLINK_IEEE_HDR_CREATE(EASYLINK_IEEE_HDR_CRC_2BYTE, EASYLINK_IEEE_HDR_WHTNG_EN, (txPacket->len + addrSize + sizeof(ieeeHdr))); hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); txBuffer[0] = (uint8_t)(ieeeHdr & 0x00FF); txBuffer[1] = (uint8_t)((ieeeHdr & 0xFF00) >> 8); } else { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); txBuffer[0] = txPacket->len + addrSize; } //EASYLINK_USE_DEFAULT_ADDR //memcpy(&txBuffer[hdrSize], defaultAddr, addrSize); // Use the default address defined in easylink_config.h //memcpy(&txBuffer[hdrSize], txPacket->dstAddr, addrSize); // Use the address passed in from the application //memcpy(&txBuffer[addrSize + hdrSize], txPacket->payload, txPacket->len); EasyLink_cmdPropTxAdv.pktLen = txPacket->len + addrSize + hdrSize; //packet length to Tx includes address and length field EasyLink_cmdPropTxAdv.pPkt = txBuffer; //cmdTime = calculateCmdTime(txPacket); //txPacket->absTime != 0 //EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_ABSTIME; //EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropTxAdv.startTime = txPacket->absTime; //schParams_prop.startTime = txPacket->absTime; //schParams_prop.startType = RF_StartAbs; //schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endTime = EasyLink_cmdPropTxAdv.startTime + EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endType = RF_EndAbs; //else EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropTxAdv.startTime = 0U; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; //schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); //schParams_prop.endTime = RF_getCurrentTime() + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; if(rfModeMultiClient) // Send packet { cmdHdl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { cmdHdl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv,RF_PriorityHigh, 0, EASYLINK_RF_EVENT_MASK); } RF_EventMask result = RF_pendCmd(rfHandle, cmdHdl, EASYLINK_RF_EVENT_MASK); // Wait for Command to complete if (result == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else if (result & RF_EventLastCmdDone) { status = EasyLink_Status_Success; } //Release the busyMutex Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_transmit(EasyLink_TxPacket *txPacket) { usprintf_mng("EasyLink_transmit\n"); EasyLink_Status status = EasyLink_Status_Tx_Error; RF_CmdHandle cmdHdl; uint32_t cmdTime; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); if ( (!configured) || suspended) {return EasyLink_Status_Config_Error;} if (txPacket->len > EASYLINK_MAX_DATA_LENGTH) {return EasyLink_Status_Param_Error;} if (Semaphore_pend(busyMutex, 0) == false) //Check and take the busyMutex {return EasyLink_Status_Busy_Error;} //uint16_t ieeeHdr = EASYLINK_IEEE_HDR_CREATE(EASYLINK_IEEE_HDR_CRC_2BYTE, EASYLINK_IEEE_HDR_WHTNG_EN, (txPacket->len + addrSize + sizeof(ieeeHdr))); //hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); //txBuffer[0] = (uint8_t)(ieeeHdr & 0x00FF); //txBuffer[1] = (uint8_t)((ieeeHdr & 0xFF00) >> 8); //hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); //txBuffer[0] = txPacket->len + addrSize; //EASYLINK_USE_DEFAULT_ADDR // Use the default address defined in easylink_config.h //memcpy(&txBuffer[hdrSize], defaultAddr, addrSize); // Use the address passed in from the application //memcpy(&txBuffer[hdrSize], txPacket->dstAddr, addrSize); memcpy(&txBuffer[addrSize + hdrSize], txPacket->payload, txPacket->len); //packet length to Tx includes address and length field EasyLink_cmdPropTxAdv.pktLen = txPacket->len + addrSize + hdrSize; EasyLink_cmdPropTxAdv.pPkt = txBuffer; cmdTime = calculateCmdTime(txPacket); EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropTxAdv.startTime = txPacket->absTime; schParams_prop.startTime = txPacket->absTime; schParams_prop.startType = RF_StartAbs; schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endTime = EasyLink_cmdPropTxAdv.startTime + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; // Send packet if(rfModeMultiClient) { cmdHdl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv,&schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { cmdHdl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv,RF_PriorityHigh, 0, EASYLINK_RF_EVENT_MASK); } // Wait for Command to complete RF_EventMask result = RF_pendCmd(rfHandle, cmdHdl, EASYLINK_RF_EVENT_MASK); if (result == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } else if (result & RF_EventLastCmdDone) { status = EasyLink_Status_Success; } usprintf_mng("EasyLink:%d\n",status); Semaphore_post(busyMutex); //Release the busyMutex return status; } //*****************************************************************************// EasyLink_Status EasyLink_transmitAsync(EasyLink_TxPacket *txPacket, EasyLink_TxDoneCb cb) { EasyLink_Status status = EasyLink_Status_Tx_Error; uint32_t cmdTime; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); //Check if not configure or already an Async command being performed if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { return EasyLink_Status_Busy_Error; } if (txPacket->len > EASYLINK_MAX_DATA_LENGTH) { return EasyLink_Status_Param_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } //store application callback txCb = cb; if(useIeeeHeader) { uint16_t ieeeHdr = EASYLINK_IEEE_HDR_CREATE(EASYLINK_IEEE_HDR_CRC_2BYTE, EASYLINK_IEEE_HDR_WHTNG_EN, (txPacket->len + addrSize + sizeof(ieeeHdr))); hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); txBuffer[0] = (uint8_t)(ieeeHdr & 0x00FF); txBuffer[1] = (uint8_t)((ieeeHdr & 0xFF00) >> 8); } else { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); txBuffer[0] = txPacket->len + addrSize; } if(EASYLINK_USE_DEFAULT_ADDR) { // Use the default address defined in easylink_config.h memcpy(&txBuffer[hdrSize], defaultAddr, addrSize); } else { // Use the address passed in from the application memcpy(&txBuffer[hdrSize], txPacket->dstAddr, addrSize); } memcpy(&txBuffer[addrSize + hdrSize], txPacket->payload, txPacket->len); //packet length to Tx includes address and length field EasyLink_cmdPropTxAdv.pktLen = txPacket->len + addrSize + hdrSize; EasyLink_cmdPropTxAdv.pPkt = txBuffer; cmdTime = calculateCmdTime(txPacket); if (txPacket->absTime != 0) { EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropTxAdv.startTime = txPacket->absTime; schParams_prop.startTime = txPacket->absTime; schParams_prop.startType = RF_StartAbs; schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endTime = EasyLink_cmdPropTxAdv.startTime + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; } else { EasyLink_cmdPropTxAdv.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropTxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropTxAdv.startTime = 0; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endTime = RF_getCurrentTime() + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; } // Send packet if(rfModeMultiClient) { asyncCmdHndl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv, &schParams_prop, txDoneCallback, EASYLINK_RF_EVENT_MASK); } else { asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropTxAdv, RF_PriorityHigh, txDoneCallback, EASYLINK_RF_EVENT_MASK); } if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { status = EasyLink_Status_Success; } else { // Error occurred. Callback will not be called, release busyMutex. Semaphore_post(busyMutex); } //busyMutex will be released by the callback return status; } //*****************************************************************************// EasyLink_Status EasyLink_transmitCcaAsync(EasyLink_TxPacket *txPacket, EasyLink_TxDoneCb cb) { EasyLink_Status status = EasyLink_Status_Tx_Error; uint32_t cmdTime; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Tx, (EasyLink_Priority)cmdPriority); //Check if not configure or already an Async command being performed, or //if a random number generator function is not provided if ( (!configured) || suspended || (!getRN)) { return EasyLink_Status_Config_Error; } if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { return EasyLink_Status_Busy_Error; } if (txPacket->len > EASYLINK_MAX_DATA_LENGTH) { return EasyLink_Status_Param_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } //store application callback txCb = cb; if(useIeeeHeader) { uint16_t ieeeHdr = EASYLINK_IEEE_HDR_CREATE(EASYLINK_IEEE_HDR_CRC_2BYTE, EASYLINK_IEEE_HDR_WHTNG_EN, (txPacket->len + addrSize + sizeof(ieeeHdr))); hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); txBuffer[0] = (uint8_t)(ieeeHdr & 0x00FF); txBuffer[1] = (uint8_t)((ieeeHdr & 0xFF00) >> 8); } else { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); txBuffer[0] = txPacket->len + addrSize; } if(EASYLINK_USE_DEFAULT_ADDR) { // Use the default address defined in easylink_config.h memcpy(&txBuffer[hdrSize], defaultAddr, addrSize); } else { // Use the address passed in from the application memcpy(&txBuffer[hdrSize], txPacket->dstAddr, addrSize); } memcpy(&txBuffer[addrSize + hdrSize], txPacket->payload, txPacket->len); // Set the Carrier Sense command attributes // Chain the TX command to run after the CS command EasyLink_cmdPropCs.pNextOp = (rfc_radioOp_t *)&EasyLink_cmdPropTxAdv; //packet length to Tx includes address and length field EasyLink_cmdPropTxAdv.pktLen = txPacket->len + addrSize + hdrSize; EasyLink_cmdPropTxAdv.pPkt = txBuffer; cmdTime = calculateCmdTime(txPacket); if (txPacket->absTime != 0) { EasyLink_cmdPropCs.startTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropCs.startTrigger.pastTrig = 1; EasyLink_cmdPropCs.startTime = txPacket->absTime; schParams_prop.startTime = txPacket->absTime; schParams_prop.startType = RF_StartAbs; schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endTime = EasyLink_cmdPropCs.startTime + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; } else { EasyLink_cmdPropCs.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropCs.startTrigger.pastTrig = 1; EasyLink_cmdPropCs.startTime = 0; schParams_prop.startTime = 0; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.duration = EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endTime = RF_getCurrentTime() + EasyLink_ms_To_RadioTime(cmdTime); schParams_prop.endType = RF_EndAbs; } // Check for a clear channel (CCA) before sending a packet if(rfModeMultiClient) { asyncCmdHndl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropCs, &schParams_prop, ccaDoneCallback, EASYLINK_RF_EVENT_MASK); } else { asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropCs, RF_PriorityHigh, ccaDoneCallback, EASYLINK_RF_EVENT_MASK); } if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { status = EasyLink_Status_Success; } else { // Error occurred. Callback will not be called, release busyMutex. Semaphore_post(busyMutex); } //busyMutex will be released by the callback return status; } //*****************************************************************************// EasyLink_Status EasyLink_receive_CBeacon(EasyLink_CBeacon *rxPacket) { usprintf_mng("EasyLink_receive_CBeacon IN\n"); unsigned char bitArray[8] = {0}; EasyLink_Status status = EasyLink_Status_Rx_Error; RF_EventMask result; rfc_dataEntryGeneral_t *pDataEntry; RF_CmdHandle rx_cmd; schParams_prop.startTime = 0U; //schParams_prop.startTime = 0; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; //schParams_prop.endTime = 0; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; //schParams_prop.duration = 0; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Rx, (EasyLink_Priority)cmdPriority); if ( (!configured) || suspended){return EasyLink_Status_Config_Error;} if (Semaphore_pend(busyMutex, 0) == false){return EasyLink_Status_Busy_Error;}//Check and take the busyMutex pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer; //data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data pDataEntry->length = 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH; pDataEntry->status = 0; dataQueue.pCurrEntry = (uint8_t*)pDataEntry; dataQueue.pLastEntry = NULL; EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */ EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics; EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropRxAdv.startTime = 0; schParams_prop.startTime = 0U; schParams_prop.startTime = 0; schParams_prop.startType = RF_StartNotSpecified; //if (rxPacket->rxTimeout != 0) //EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME; //EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; //EasyLink_cmdPropRxAdv.endTime = RF_getCurrentTime() + rxPacket->rxTimeout; //schParams_prop.endTime = EasyLink_cmdPropRxAdv.endTime; //schParams_prop.endType = RF_EndAbs; EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER; EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.endTime = 0; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; //Clear the Rx statistics structure memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t)); //if(rfModeMultiClient) //rx_cmd = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,&schParams_prop, 0, EASYLINK_RF_EVENT_MASK); rx_cmd = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,RF_PriorityHigh, 0, EASYLINK_RF_EVENT_MASK); /* Wait for Command to complete */ result = RF_pendCmd(rfHandle, rx_cmd, RF_EventLastCmdDone); rxPacket->len = *(uint8_t*)(&pDataEntry->data); memcpy(bitArray, (&pDataEntry->data+1), rxPacket->len); usprintf_mng("if:%02x %02x %02x %02x %02x %02x %02x %02x\n",bitArray[0],bitArray[1], bitArray[2],bitArray[3],bitArray[4],bitArray[5],bitArray[6],bitArray[7]); if (result & RF_EventLastCmdDone) { if (EasyLink_cmdPropRxAdv.status == PROP_DONE_OK) //Check command status { if (pDataEntry->status != DATA_ENTRY_FINISHED) //Check that data entry status indicates it is finished with { status = EasyLink_Status_Rx_Error; } //check Rx Statistics else if ( (rxStatistics.nRxOk == 1) || ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) && (rxStatistics.nRxIgnored == 1)) ) //or filer disabled and ignore due to addr mistmatch { //copy length from pDataEntry (- addrSize) rxPacket->len = *(uint8_t*)(&pDataEntry->data) - addrSize; if(useIeeeHeader) { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); } else { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); } //copy address //memcpy(rxPacket->dstAddr, (&pDataEntry->data + hdrSize), addrSize); //copy payload //memcpy(&rxPacket->payload, (&pDataEntry->data + hdrSize + addrSize), (rxPacket->len)); //rxPacket->rssi = rxStatistics.lastRssi; rxPacket->len = *(uint8_t*)(&pDataEntry->data); memcpy(bitArray, (&pDataEntry->data+1), rxPacket->len); usprintf_mng("EasyLink_Status_Success\n"); usprintf_mng("Receve:%02x %02x %02x %02x %02x %02x %02x %02x\n",bitArray[0],bitArray[1], bitArray[2],bitArray[3],bitArray[4],bitArray[5],bitArray[6],bitArray[7]); /*****************************************/ rxPacket->fCBeacon.TimeStamp=NULL; //Make any bit 32 TimeStamp rxPacket->fCBeacon.TimeStamp|=bitArray[7]; rxPacket->fCBeacon.TimeStamp|=bitArray[6]<<8; rxPacket->fCBeacon.TimeStamp|=bitArray[5]<<16; rxPacket->fCBeacon.TimeStamp|=bitArray[4]<<24; rxPacket->fCBeacon.InitialState=NULL; //Make any bit 1 InitialState rxPacket->fCBeacon.InitialState|=bitArray[3]&0x01; rxPacket->fCBeacon.DCHChannelNum=NULL; //Make any bit 6 DCHChannelNum rxPacket->fCBeacon.DCHChannelNum|=(bitArray[3]&0x7e)>>1; rxPacket->fCBeacon.DutyCycling=NULL; //Make any bit 2 DutyCycling rxPacket->fCBeacon.DutyCycling|=(bitArray[3]&0x80)>>7; rxPacket->fCBeacon.DutyCycling|=(bitArray[2]&0x01)<<1; rxPacket->fCBeacon.InterferenceMitigation=NULL; //Make any bit 1 InterferenceMitigation rxPacket->fCBeacon.InterferenceMitigation|=(bitArray[2]&0x02)>>1; rxPacket->fCBeacon.Reser_1=NULL; //Make any bit 1 Reserved rxPacket->fCBeacon.Reser_1|=(bitArray[2]&0x04)>>2; rxPacket->fCBeacon.TimeSlots=NULL; //Make any bit 10 TimeSlots rxPacket->fCBeacon.TimeSlots|=(bitArray[2]&0xf8)>>3; rxPacket->fCBeacon.TimeSlots|=(bitArray[1]&0x1f)<<5; rxPacket->fCBeacon.SlotLen=NULL; //Make any bit 3 SlotLen rxPacket->fCBeacon.SlotLen|=(bitArray[1]&0xe0)>>5; rxPacket->fCBeacon.HubAddr=bitArray[0]; //Make any bit 8 HubAddr /******************************************/ status = EasyLink_Status_Success; //rxPacket->absTime = rxStatistics.timeStamp; } else if ( rxStatistics.nRxBufFull == 1) { status = EasyLink_Status_Rx_Buffer_Error; } else if ( rxStatistics.nRxStopped == 1) { status = EasyLink_Status_Aborted; } else { status = EasyLink_Status_Rx_Error; } } else if ( EasyLink_cmdPropRxAdv.status == PROP_DONE_RXTIMEOUT) { status = EasyLink_Status_Rx_Timeout; } else { status = EasyLink_Status_Rx_Error; } } else if (result == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } //Release the busyMutex Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_receive_DBeacon(EasyLink_DBeacon *rxPacket) { unsigned char bitArray[13] = {0}; EasyLink_Status status = EasyLink_Status_Rx_Error; RF_EventMask result; rfc_dataEntryGeneral_t *pDataEntry; RF_CmdHandle rx_cmd; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Rx, (EasyLink_Priority)cmdPriority); if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer; //data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data pDataEntry->length = 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH; pDataEntry->status = 0; dataQueue.pCurrEntry = (uint8_t*)pDataEntry; dataQueue.pLastEntry = NULL; EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */ EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics; //if (rxPacket->absTime != 0) //EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_ABSTIME; //EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropRxAdv.startTime = rxPacket->absTime; //schParams_prop.startTime = rxPacket->absTime; //schParams_prop.startType = RF_StartAbs; EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.startTime = 0; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; //if (rxPacket->rxTimeout != 0) // EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME; //EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; //EasyLink_cmdPropRxAdv.endTime = RF_getCurrentTime() + rxPacket->rxTimeout; //schParams_prop.endTime = EasyLink_cmdPropRxAdv.endTime; //schParams_prop.endType = RF_EndAbs; EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER; EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.endTime = 0; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; //Clear the Rx statistics structure memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t)); if(rfModeMultiClient) { rx_cmd = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { rx_cmd = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv, RF_PriorityHigh, 0, EASYLINK_RF_EVENT_MASK); } /* Wait for Command to complete */ result = RF_pendCmd(rfHandle, rx_cmd, RF_EventLastCmdDone); if (result & RF_EventLastCmdDone) { //Check command status if (EasyLink_cmdPropRxAdv.status == PROP_DONE_OK) { //Check that data entry status indicates it is finished with if (pDataEntry->status != DATA_ENTRY_FINISHED) { status = EasyLink_Status_Rx_Error; } //check Rx Statistics else if ( (rxStatistics.nRxOk == 1) || //or filer disabled and ignore due to addr mistmatch ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) && (rxStatistics.nRxIgnored == 1)) ) { //copy length from pDataEntry (- addrSize) rxPacket->len = *(uint8_t*)(&pDataEntry->data) - addrSize; if(useIeeeHeader) { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); } else { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); } //copy address //memcpy(rxPacket->dstAddr, (&pDataEntry->data + hdrSize), addrSize); //copy payload //memcpy(&rxPacket->payload, (&pDataEntry->data + hdrSize + addrSize), (rxPacket->len)); //rxPacket->rssi = rxStatistics.lastRssi; rxPacket->len = *(uint8_t*)(&pDataEntry->data); memcpy(bitArray, (&pDataEntry->data+1), rxPacket->len); usprintf_mng("Receve:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", bitArray[0],bitArray[1],bitArray[2],bitArray[3],bitArray[4],bitArray[5],bitArray[6],bitArray[7],bitArray[8],bitArray[9],bitArray[11],bitArray[12]); /*****************************************/ rxPacket->fDBeacon.Reserved=NULL; //Make any bit 2 Reserved rxPacket->fDBeacon.Reserved|=bitArray[12]&0x03; rxPacket->fDBeacon.ChannelNumber=NULL; //Make any bit 6 ChannelNumber rxPacket->fDBeacon.ChannelNumber|=(bitArray[12]&0xfa)>>2; rxPacket->fDBeacon.ChangeTiming=bitArray[11]; //Make any bit 8 ChangeTiming rxPacket->fDBeacon.SlotReassignmentTimung=bitArray[10]; //Make any bit 8 SlotReassignment rxPacket->fDBeacon.DSRList=NULL; //Make any bit 16 DSRList rxPacket->fDBeacon.DSRList|=bitArray[9]; rxPacket->fDBeacon.DSRList|=bitArray[8]<<8; rxPacket->fDBeacon.TimeStamp=NULL; //Make any bit 24 TimeStamp rxPacket->fDBeacon.TimeStamp|=bitArray[7]; rxPacket->fDBeacon.TimeStamp|=bitArray[6]<<8; rxPacket->fDBeacon.TimeStamp|=bitArray[5]<<16; rxPacket->fDBeacon.MultiuseAccess=NULL; //Make any bit 1 MultiuseAccess rxPacket->fDBeacon.MultiuseAccess|=bitArray[4]&0x01; rxPacket->fDBeacon.ChannelMigration=NULL; //Make any bit 1 ChannelMigration rxPacket->fDBeacon.ChannelMigration|=(bitArray[4]&0x02)>>1; rxPacket->fDBeacon.SlotReassignment=NULL; //Make any bit 1 SlitRessignment rxPacket->fDBeacon.SlotReassignment|=(bitArray[4]&0x04)>>2; rxPacket->fDBeacon.DownlinkData=NULL; //Make any bit 1 DownlinkData rxPacket->fDBeacon.DownlinkData|=(bitArray[4]&0x08)>>3; rxPacket->fDBeacon.InactiveStartSlot=NULL; //Make any bit 8 InactiveStartSlot rxPacket->fDBeacon.InactiveStartSlot|=(bitArray[4]&0xf0)>>4; rxPacket->fDBeacon.InactiveStartSlot|=(bitArray[3]&0x0f)<<4; rxPacket->fDBeacon.CMStartSlot=NULL; //Make any bit 10 CMStartSlot rxPacket->fDBeacon.CMStartSlot|=(bitArray[3]&0xf0)>>4; rxPacket->fDBeacon.CMStartSlot|=(bitArray[2]&0x3f)<<4; rxPacket->fDBeacon.IBI_Totalslots=NULL; //Make any bit 10 IBI_Totalslots rxPacket->fDBeacon.IBI_Totalslots|=(bitArray[2]&0xc0)>>6; rxPacket->fDBeacon.IBI_Totalslots|=bitArray[1]<<2; rxPacket->fDBeacon.HubAddr=bitArray[0]; //Make any bit 8 HubAddr /*****************************************/ status = EasyLink_Status_Success; //rxPacket->absTime = rxStatistics.timeStamp; } else if ( rxStatistics.nRxBufFull == 1) { status = EasyLink_Status_Rx_Buffer_Error; } else if ( rxStatistics.nRxStopped == 1) { status = EasyLink_Status_Aborted; } else { status = EasyLink_Status_Rx_Error; } } else if ( EasyLink_cmdPropRxAdv.status == PROP_DONE_RXTIMEOUT) { status = EasyLink_Status_Rx_Timeout; } else { status = EasyLink_Status_Rx_Error; } } else if (result == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } //Release the busyMutex Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_receive(EasyLink_RxPacket *rxPacket) { usprintf_mng("EasyLink_receive\n"); EasyLink_Status status = EasyLink_Status_Rx_Error; RF_EventMask result; rfc_dataEntryGeneral_t *pDataEntry; RF_CmdHandle rx_cmd; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Rx, (EasyLink_Priority)cmdPriority); if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer; //data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data pDataEntry->length = 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH; pDataEntry->status = 0; dataQueue.pCurrEntry = (uint8_t*)pDataEntry; dataQueue.pLastEntry = NULL; EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */ EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics; if (rxPacket->absTime != 0) { EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.startTime = rxPacket->absTime; schParams_prop.startTime = rxPacket->absTime; schParams_prop.startType = RF_StartAbs; } else { EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.startTime = 0; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; } if (rxPacket->rxTimeout != 0) { EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.endTime = RF_getCurrentTime() + rxPacket->rxTimeout; schParams_prop.endTime = EasyLink_cmdPropRxAdv.endTime; schParams_prop.endType = RF_EndAbs; } else { EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER; EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.endTime = 0; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; } //Clear the Rx statistics structure memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t)); if(rfModeMultiClient) { rx_cmd = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv, &schParams_prop, 0, EASYLINK_RF_EVENT_MASK); } else { rx_cmd = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv, RF_PriorityHigh, 0, EASYLINK_RF_EVENT_MASK); } /* Wait for Command to complete */ result = RF_pendCmd(rfHandle, rx_cmd, RF_EventLastCmdDone); if (result & RF_EventLastCmdDone) { //Check command status if (EasyLink_cmdPropRxAdv.status == PROP_DONE_OK) { //Check that data entry status indicates it is finished with if (pDataEntry->status != DATA_ENTRY_FINISHED) { status = EasyLink_Status_Rx_Error; } //check Rx Statistics else if ( (rxStatistics.nRxOk == 1) || //or filer disabled and ignore due to addr mistmatch ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) && (rxStatistics.nRxIgnored == 1)) ) { //copy length from pDataEntry (- addrSize) rxPacket->len = *(uint8_t*)(&pDataEntry->data) - addrSize; if(useIeeeHeader) { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_IEEE_HDR_NBITS); } else { hdrSize = EASYLINK_HDR_SIZE_NBYTES(EASYLINK_PROP_HDR_NBITS); } //copy address memcpy(rxPacket->dstAddr, (&pDataEntry->data + hdrSize), addrSize); //copy payload memcpy(&rxPacket->payload, (&pDataEntry->data + hdrSize + addrSize), (rxPacket->len)); rxPacket->rssi = rxStatistics.lastRssi; usprintf_mng("EasyLink_Status_Success:%d\n",rxPacket->dstAddr); status = EasyLink_Status_Success; rxPacket->absTime = rxStatistics.timeStamp; } else if ( rxStatistics.nRxBufFull == 1) { status = EasyLink_Status_Rx_Buffer_Error; } else if ( rxStatistics.nRxStopped == 1) { status = EasyLink_Status_Aborted; } else { status = EasyLink_Status_Rx_Error; } } else if ( EasyLink_cmdPropRxAdv.status == PROP_DONE_RXTIMEOUT) { status = EasyLink_Status_Rx_Timeout; } else { status = EasyLink_Status_Rx_Error; } } else if (result == (RF_EventCmdCancelled | RF_EventCmdPreempted)) { status = EasyLink_Status_Cmd_Rejected; } //Release the busyMutex Semaphore_post(busyMutex); usprintf_mng("EasyLink_receive:%d\n",status); return status; } //*****************************************************************************// EasyLink_Status EasyLink_receiveAsync_CBeacon(EasyLink_CBReceiveCb cb,EasyLink_CBeacon *txPacket,EasyLink_TimeStamp TimeStamp) { EasyLink_Status status = EasyLink_Status_Rx_Error; rfc_dataEntryGeneral_t *pDataEntry; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Rx, (EasyLink_Priority)cmdPriority); if ( (!configured) || suspended) //Check if not configure of already an Async command being performed {return EasyLink_Status_Config_Error;} if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) {return EasyLink_Status_Busy_Error;} if (Semaphore_pend(busyMutex, 0) == false) //Check and take the busyMutex {return EasyLink_Status_Busy_Error;} CBrxCb = cb; //rxCb = cb; pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer; //data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data pDataEntry->length = 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH; pDataEntry->status = 0; dataQueue.pCurrEntry = (uint8_t*)pDataEntry; dataQueue.pLastEntry = NULL; EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */ EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics; //if (absTime != 0) //EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_ABSTIME; //EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; //EasyLink_cmdPropRxAdv.startTime = absTime; //schParams_prop.startTime = absTime; //schParams_prop.startType = RF_StartAbs; EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.startTime = 0; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; //if (asyncRxTimeOut != 0) EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.endTime = TimeStamp.EndTime; schParams_prop.endTime = TimeStamp.EndTime; schParams_prop.endType = RF_EndAbs; //EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER; //EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; //EasyLink_cmdPropRxAdv.endTime = 0; //schParams_prop.endTime = 0U; //schParams_prop.endType = RF_EndNotSpecified; //Clear the Rx statistics structure memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t)); //if(rfModeMultiClient) //asyncCmdHndl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,&schParams_prop, rxDoneCallback_CBeacon, EASYLINK_RF_EVENT_MASK); asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,RF_PriorityHigh, rxDoneCallback_CBeacon, EASYLINK_RF_EVENT_MASK); if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { status = EasyLink_Status_Success; } else { Semaphore_post(busyMutex); //Callback will not be called, release the busyMutex } //busyMutex will be released in callback return status; } //*****************************************************************************// EasyLink_Status EasyLink_receiveAsync(EasyLink_ReceiveCb cb, uint32_t absTime) { EasyLink_Status status = EasyLink_Status_Rx_Error; rfc_dataEntryGeneral_t *pDataEntry; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; schParams_prop.allowDelay = RF_AllowDelayNone; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; schParams_prop.duration = 0U; schParams_prop.activityInfo = genActivityTableValue(EasyLink_Activity_Rx, (EasyLink_Priority)cmdPriority); //Check if not configure of already an Async command being performed if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { return EasyLink_Status_Busy_Error; } //Check and take the busyMutex if (Semaphore_pend(busyMutex, 0) == false) { return EasyLink_Status_Busy_Error; } rxCb = cb; pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer; //data entry rx buffer includes hdr (len-1Byte), addr (max 8Bytes) and data pDataEntry->length = 1 + EASYLINK_MAX_ADDR_SIZE + EASYLINK_MAX_DATA_LENGTH; pDataEntry->status = 0; dataQueue.pCurrEntry = (uint8_t*)pDataEntry; dataQueue.pLastEntry = NULL; EasyLink_cmdPropRxAdv.pQueue = &dataQueue; /* Set the Data Entity queue for received data */ EasyLink_cmdPropRxAdv.pOutput = (uint8_t*)&rxStatistics; if (absTime != 0) { EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.startTime = absTime; schParams_prop.startTime = absTime; schParams_prop.startType = RF_StartAbs; } else { EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW; EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.startTime = 0; schParams_prop.startTime = 0U; schParams_prop.startType = RF_StartNotSpecified; } if (asyncRxTimeOut != 0) { EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME; EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.endTime = RF_getCurrentTime() + asyncRxTimeOut; schParams_prop.endTime = EasyLink_cmdPropRxAdv.endTime; schParams_prop.endType = RF_EndAbs; } else { EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER; EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1; EasyLink_cmdPropRxAdv.endTime = 0; schParams_prop.endTime = 0U; schParams_prop.endType = RF_EndNotSpecified; } //Clear the Rx statistics structure memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t)); if(rfModeMultiClient) { asyncCmdHndl = RF_scheduleCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv, &schParams_prop, rxDoneCallback, EASYLINK_RF_EVENT_MASK); } else { asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv, RF_PriorityHigh, rxDoneCallback, EASYLINK_RF_EVENT_MASK); } if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { status = EasyLink_Status_Success; } else { //Callback will not be called, release the busyMutex Semaphore_post(busyMutex); } //busyMutex will be released in callback return status; } //*****************************************************************************// EasyLink_Status EasyLink_abort(void) { EasyLink_Status status = EasyLink_Status_Cmd_Error; if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } //check an Async command is running, if not return success if (!EasyLink_CmdHandle_isValid(asyncCmdHndl)) { return EasyLink_Status_Aborted; } //force abort (graceful param set to 0) if (RF_cancelCmd(rfHandle, asyncCmdHndl, 0) == RF_StatSuccess) { /* If command is cancelled immediately, callback may have set the cmd handle to invalid. * In that case, no need to pend. */ if (EasyLink_CmdHandle_isValid(asyncCmdHndl)) { /* Wait for Command to complete */ RF_EventMask result = RF_pendCmd(rfHandle, asyncCmdHndl, (RF_EventLastCmdDone | RF_EventCmdAborted | RF_EventCmdCancelled | RF_EventCmdStopped)); if (result & RF_EventLastCmdDone) { status = EasyLink_Status_Success; } } else { /* Command already cancelled */ status = EasyLink_Status_Success; } } else { status = EasyLink_Status_Cmd_Error; } return status; } //*****************************************************************************// EasyLink_Status EasyLink_enableRxAddrFilter(uint8_t* pui8AddrFilterTable, uint8_t ui8AddrSize, uint8_t ui8NumAddrs) { EasyLink_Status status = EasyLink_Status_Param_Error; if ( (!configured) || suspended) { return EasyLink_Status_Config_Error; } if (isAddrSizeValid(ui8AddrSize) == false) { return EasyLink_Status_Param_Error; } if ( Semaphore_pend(busyMutex, 0) == false ) { return EasyLink_Status_Busy_Error; } if ( (pui8AddrFilterTable != NULL) && (ui8AddrSize != 0) && (ui8NumAddrs != 0) && (ui8AddrSize == addrSize) && (ui8NumAddrs <= EASYLINK_MAX_ADDR_FILTERS) ) { memcpy(addrFilterTable, pui8AddrFilterTable, ui8AddrSize * ui8NumAddrs); EasyLink_cmdPropRxAdv.addrConf.addrSize = ui8AddrSize; EasyLink_cmdPropRxAdv.addrConf.numAddr = ui8NumAddrs; EasyLink_cmdPropRxAdv.pktConf.filterOp = 0; status = EasyLink_Status_Success; } else if (pui8AddrFilterTable == NULL) { //disable filter EasyLink_cmdPropRxAdv.pktConf.filterOp = 1; status = EasyLink_Status_Success; } //Release the busyMutex Semaphore_post(busyMutex); return status; } //*****************************************************************************// EasyLink_Status EasyLink_setCtrl(EasyLink_CtrlOption Ctrl, uint32_t ui32Value) { EasyLink_Status status = EasyLink_Status_Param_Error; switch(Ctrl) { case EasyLink_Ctrl_AddSize: if (isAddrSizeValid(ui32Value)) { addrSize = (uint8_t) ui32Value; EasyLink_cmdPropRxAdv.addrConf.addrSize = addrSize; status = EasyLink_Status_Success; } break; case EasyLink_Ctrl_Idle_TimeOut: if(configured) { // Client has already been configured, need to modify // the client configuration directly RF_control(rfHandle, RF_CTRL_SET_INACTIVITY_TIMEOUT, &ui32Value); } else { // RF_open() in EasyLink_init() has not been called yet so it // is safe to alter the rfParams inactivityTimeout = ui32Value; } status = EasyLink_Status_Success; break; case EasyLink_Ctrl_MultiClient_Mode: rfModeMultiClient = (bool) ui32Value; status = EasyLink_Status_Success; break; case EasyLink_Ctrl_AsyncRx_TimeOut: asyncRxTimeOut = ui32Value; status = EasyLink_Status_Success; break; case EasyLink_Ctrl_Cmd_Priority: if(ui32Value < EasyLink_Priority_NEntries) { cmdPriority = (EasyLink_Priority)ui32Value; status = EasyLink_Status_Success; } break; case EasyLink_Ctrl_Test_Tone: status = enableTestMode(EasyLink_Ctrl_Test_Tone); break; case EasyLink_Ctrl_Test_Signal: status = enableTestMode(EasyLink_Ctrl_Test_Signal); break; case EasyLink_Ctrl_Rx_Test_Tone: status = enableTestMode(EasyLink_Ctrl_Rx_Test_Tone); break; } return status; } //*****************************************************************************// EasyLink_Status EasyLink_getCtrl(EasyLink_CtrlOption Ctrl, uint32_t* pui32Value) { EasyLink_Status status = EasyLink_Status_Cmd_Error; switch(Ctrl) { case EasyLink_Ctrl_AddSize: *pui32Value = addrSize; status = EasyLink_Status_Success; break; case EasyLink_Ctrl_Idle_TimeOut: *pui32Value = rfParams.nInactivityTimeout; status = EasyLink_Status_Success; break; case EasyLink_Ctrl_MultiClient_Mode: *pui32Value = (uint32_t) rfModeMultiClient; status = EasyLink_Status_Success; break; case EasyLink_Ctrl_AsyncRx_TimeOut: *pui32Value = asyncRxTimeOut; status = EasyLink_Status_Success; break; case EasyLink_Ctrl_Cmd_Priority: *pui32Value = cmdPriority; status = EasyLink_Status_Success; break; case EasyLink_Ctrl_Test_Tone: case EasyLink_Ctrl_Test_Signal: case EasyLink_Ctrl_Rx_Test_Tone: *pui32Value = 0; status = EasyLink_Status_Success; break; } return status; } //*****************************************************************************// EasyLink_Status EasyLink_getIeeeAddr(uint8_t *ieeeAddr) { EasyLink_Status status = EasyLink_Status_Param_Error; if (ieeeAddr != NULL) { int i; //Reading from primary IEEE location... uint8_t *location = (uint8_t *)EASYLINK_PRIMARY_IEEE_ADDR_LOCATION; /* * ...unless we can find a byte != 0xFF in secondary * * Intentionally checking all 8 bytes here instead of len, because we * are checking validity of the entire IEEE address irrespective of the * actual number of bytes the caller wants to copy over. */ for (i = 0; i < 8; i++) { if (((uint8_t *)EASYLINK_SECONDARY_IEEE_ADDR_LOCATION)[i] != 0xFF) { //A byte in the secondary location is not 0xFF. Use the //secondary location = (uint8_t *)EASYLINK_SECONDARY_IEEE_ADDR_LOCATION; break; } } //inverting byte order for (i = 0; i < 8; i++) { ieeeAddr[i] = location[8 - 1 - i]; } status = EasyLink_Status_Success; } return status; }
//***************************************************************************** #ifndef Easylink__include #define Easylink__include //***************************************************************************** #include <stdbool.h> #include <stdint.h> #include <ti/drivers/rf/RF.h> #include <stdlib.h> #include "ti_easylink_config.h" #include "ti_drivers_config.h" #include "ti_radio_config.h" #define EASYLINK_API_VERSION "EasyLink-v4.40.00" //! \brief EasyLink API Version #define EASYLINK_MAX_ADDR_SIZE 8 //! \brief defines the Tx/Rx Max Address Size #define EASYLINK_MAX_ADDR_FILTERS 8 //! \brief defines the Max number of Rx Address filters #define EASYLINK_WHITENING_MODE 2 //! \brief defines the whitening mode #define EasyLink_RadioTime_To_ms(radioTime) (radioTime / (4000000/1000)) //! \brief macro to convert from Radio Time Ticks to ms #define EasyLink_ms_To_RadioTime(ms) (ms*(4000000/1000)) //! \brief macro to convert from ms to Radio Time Ticks #define EasyLink_us_To_RadioTime(us) (us*(4000000/1000000)) //! \brief macro to convert from us to Radio Time Ticks typedef enum //! \brief EasyLink Status and error codes { EasyLink_Status_Success = 0, //!< Success EasyLink_Status_Config_Error = 1, //!< Configuration error EasyLink_Status_Param_Error = 2, //!< Param error EasyLink_Status_Mem_Error = 3, //!< Memory Error EasyLink_Status_Cmd_Error = 4, //!< Memory Error EasyLink_Status_Tx_Error = 5, //!< Tx Error EasyLink_Status_Rx_Error = 6, //!< Rx Error EasyLink_Status_Rx_Timeout = 7, //!< Rx Error EasyLink_Status_Rx_Buffer_Error = 8, //!< Rx Buffer Error EasyLink_Status_Busy_Error = 9, //!< Busy Error EasyLink_Status_Aborted = 10, //!< Command stopped or aborted EasyLink_Status_Cmd_Rejected = 11, //!< Command Rejected by RF Driver (Scheduling conflict) } EasyLink_Status; #define EasyLink_PHY_CUSTOM 0 //! \brief Phy Type defines so we can use them in checks #define EasyLink_PHY_50KBPS2GFSK 1 #define EasyLink_PHY_625BPSLRM 2 #define EasyLink_PHY_2_4_200KBPS2GFSK 3 #define EasyLink_PHY_5KBPSSLLR 4 #define EasyLink_PHY_2_4_100KBPS2GFSK 5 #define EasyLink_PHY_2_4_250KBPS2GFSK 6 #define EasyLink_PHY_200KBPS2GFSK 7 //! \brief Phy Type passed to EasyLink_init() typedef enum { EasyLink_Phy_Custom = EasyLink_PHY_CUSTOM, //!< Customer Phy specific settings exported from SmartRF Studio EasyLink_Phy_50kbps2gfsk = EasyLink_PHY_50KBPS2GFSK, //!< Phy settings for Sub1G 50kbps data rate, IEEE 802.15.4g GFSK. EasyLink_Phy_625bpsLrm = EasyLink_PHY_625BPSLRM, //!< Phy settings for Sub1G 625bps data rate, Long Range Mode. EasyLink_Phy_2_4_200kbps2gfsk = EasyLink_PHY_2_4_200KBPS2GFSK, //!< Phy settings for 2.4Ghz 200kbps data rate, IEEE 802.15.4g GFSK. EasyLink_Phy_5kbpsSlLr = EasyLink_PHY_5KBPSSLLR, //!< SimpleLink Long Range (5 kbps) EasyLink_Phy_2_4_100kbps2gfsk = EasyLink_PHY_2_4_100KBPS2GFSK, //!< Phy settings for 2.4Ghz 100kbps data rate, IEEE 802.15.4g GFSK. EasyLink_Phy_2_4_250kbps2gfsk = EasyLink_PHY_2_4_250KBPS2GFSK, //!< Phy settings for 2.4Ghz 250kbps data rate, IEEE 802.15.4g GFSK. EasyLink_Phy_200kbps2gfsk = EasyLink_PHY_200KBPS2GFSK, //!< Phy settings for 200kbps data rate, IEEE 802.15.4g GFSK. EasyLink_Num_Phy_Settings, } EasyLink_PhyType; //! \brief Advance configuration options typedef enum { EasyLink_Ctrl_AddSize = 0, //!< Set the number of bytes in Addr for both Addr //!< Filter and Tx/Rx operations EasyLink_Ctrl_Idle_TimeOut = 1, //!< Set a timeout value for inactivity on the radio, //!< i.e. if the radio stays idle for this amount of //!< time it is automatically powered down EasyLink_Ctrl_MultiClient_Mode = 2, //!< Set Multiclient mode for application //!< that will use multiple RF clients. //!< Must be set before calling //!< EasyLink_init(). EasyLink_Ctrl_AsyncRx_TimeOut = 3, //!< Relative time in ticks from Async //!< Rx start to TimeOut. A value of //!< 0 means no timeout EasyLink_Ctrl_Cmd_Priority = 4, //!< Set the command priority with a value //!< from EasyLink_Priority EasyLink_Ctrl_Test_Tone = 5, //!< Enable/Disable Test mode for Tone EasyLink_Ctrl_Test_Signal = 6, //!< Enable/Disable Test mode for Signal EasyLink_Ctrl_Rx_Test_Tone = 7, //!< Enable/Disable Rx Test mode for Tone } EasyLink_CtrlOption; //! \brief Activity table //! //! +--------------+--------------------------------------+ //! | Activity | Priority | //! +--------------+------------+------------+------------+ //! | | Normal | High | Urgent | //! | TX | 0X03090000 | 0X03090001 | 0X03090002 | //! | RX | 0X03070000 | 0X03070001 | 0X03070002 | //! +--------------+--------------------------------------+ //! typedef enum{ EasyLink_Activity_Tx = 0x309, //!< Activity code for the Tx operation EasyLink_Activity_Rx = 0x307, //!< Activity code for the Rx operation }EasyLink_Activity; //! \brief Transmit and Receive Command Priority - These are only applicable in //! a multi-client use-case typedef enum{ EasyLink_Priority_Normal = 0x0, EasyLink_Priority_High = 0x1, EasyLink_Priority_Urgent = 0x2, EasyLink_Priority_NEntries }EasyLink_Priority; //! \brief EasyLink 32-bit Random number generator function type used in the //! clear channel assessment algorithm. typedef uint32_t (*EasyLink_GetRandomNumber)(void); //! \brief Structure for EasyLink_init() and EasyLink_Params_init() typedef struct { EasyLink_PhyType ui32ModType; //!< PHY type RF_ClientCallback pClientEventCb; //!< Client event callback function RF_ClientEventMask nClientEventMask;//!< Client event mask EasyLink_GetRandomNumber pGrnFxn; //!< Pointer to function that returns a 32-bit unsigned random number } EasyLink_Params; //! \brief Structure for EasyLink_init() containing pointers to all the commands //! necessary to define an RF setting typedef struct { EasyLink_PhyType EasyLink_phyType; //!< The PHY type that this RF setting //!< defines RF_Mode *RF_pProp; //!< Pointer to RF Mode Command union{ #if ((defined LAUNCHXL_CC1352P1) || (defined LAUNCHXL_CC1352P_2) || \ (defined LAUNCHXL_CC1352P_4)|| (defined LP_CC1352P7_1) || \ (defined LP_CC1352P7_4) || (defined CONFIG_LP_CC2652PSIP) || \ (defined CONFIG_CC2652P1FSIP)) rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t *RF_pCmdPropRadioDivSetup; #else rfc_CMD_PROP_RADIO_DIV_SETUP_t *RF_pCmdPropRadioDivSetup; #endif rfc_CMD_PROP_RADIO_SETUP_t *RF_pCmdPropRadioSetup; }RF_uCmdPropRadio; //!< Union containing either a pointer //!< to a divided radio setup command or //!< a pointer to a radio setup command rfc_CMD_FS_t *RF_pCmdFs; //!< Pointer to a frequency setup command rfc_CMD_PROP_TX_t *RF_pCmdPropTx; //!< Pointer to a RF TX command rfc_CMD_PROP_TX_ADV_t *RF_pCmdPropTxAdv; //!< Pointer to an advanced RF TX //!< command rfc_CMD_PROP_RX_ADV_t *RF_pCmdPropRxAdv; //!< Pointer to an advanced RF RX //!< command RF_TxPowerTable_Entry *RF_pTxPowerTable; //!< Pointer to a Tx power table uint8_t RF_txPowerTableSize; //!< Tx power table size }EasyLink_RfSetting; //! \brief Structure for the TX Packet typedef struct { uint8_t dstAddr[8]; //!< Destination address uint32_t absTime; //!< Absolute time to Tx packet (0 for immediate) //!< Layer will use last SeqNum used + 1 uint8_t len; //!< Payload Length uint8_t payload[EASYLINK_MAX_DATA_LENGTH]; //!< Payload } EasyLink_TxPacket; //! \brief Structure for the RX'ed Packet typedef struct { uint8_t dstAddr[8]; //!< Dst Address of RX'ed packet int8_t rssi; //!< rssi of RX'ed packet uint32_t absTime; //!< Absolute time to turn on Rx when passed //!< (0 for immediate), Or Absolute time that packet was Rx //!< when returned. uint32_t rxTimeout; //!< Relative time in ticks from Rx start to Rx TimeOut //!< a value of 0 means no timeout uint8_t len; //!< length of RX'ed packet uint8_t payload[EASYLINK_MAX_DATA_LENGTH]; //!< payload of RX'ed packet } EasyLink_RxPacket; typedef struct EasyLink_RxPacket EasyLink_RxPacke; //*****************************************************************************// //***************************** SmartBAN structure ****************************// //*****************************************************************************//Clock struct ClockTimeStamp { uint32_t StartTime; uint32_t EndTime; }; typedef struct ClockTimeStamp EasyLink_TimeStamp; //*****************************************************************************//C-Beacon(104bit) struct CBeaconFrameFormat { uint8_t HubAddr; //8 uint8_t SlotLen; //3 uint16_t TimeSlots; //10 uint8_t Reser_1; //1 uint8_t InterferenceMitigation; //1 uint8_t DutyCycling; //2 uint8_t DCHChannelNum; //6 uint8_t InitialState; //1 uint32_t TimeStamp; //32 uint8_t PHYver; //3 uint8_t Reser_2; //3 uint8_t NrOfNodes; //4 uint8_t DestChannel; //6 }; struct CBeaconFrame { uint8_t len; struct CBeaconFrameFormat fCBeacon; }; typedef struct CBeaconFrame EasyLink_CBeacon; //*****************************************************************************//D-Beacon(144bit 18Byte) struct DBeaconFrameFormat { uint8_t HubAddr; //8 uint16_t IBI_Totalslots; //10 uint16_t CMStartSlot; //10 uint8_t InactiveStartSlot; //8 uint8_t DownlinkData; //1 uint8_t SlotReassignment; //1 uint8_t ChannelMigration; //1 uint8_t MultiuseAccess; //1 uint32_t TimeStamp; //24 uint16_t DSRList; //16 uint8_t SlotReassignmentTimung; //8 uint8_t ChangeTiming; //8 uint8_t ChannelNumber; //6 uint8_t Reserved; //2 }; struct DBeaconFrame { uint8_t len; struct DBeaconFrameFormat fDBeacon; }; typedef struct DBeaconFrame EasyLink_DBeacon; //*****************************************************************************//C-Req(192 Reserved_3bit) struct CRequestFrameFormat { uint8_t RecipientAddress; //8 uint8_t SenderAddress; //8 uint8_t MultiUseAccess; //1 uint8_t PHYCapability; //4 uint8_t RequestedWakeupPhase; //8 uint16_t RequestedWakeupPeriod; //16 uint64_t UplinKRequest; //32 uint64_t DownlinkRequest; //32 uint8_t Reserved; //3 }; struct CRequestFrame { uint8_t len; struct CRequestFrameFormat fCReq; }; typedef struct CRequestFrame EasyLink_CReq; //*****************************************************************************//Mac General Frame Format(Total 24) struct FrameControl { uint8_t ProtocolVersion; //3; uint8_t AckPolicy; //1; uint8_t FrameType; //2; uint8_t FrameSubtype; //3; uint8_t SequenceNum; //8; uint8_t FragmentNum; //3; uint8_t NofinalFrag; //1; uint8_t CommandAck; //1; uint8_t Reserved; //2; }; struct MacFrameBody { //Total 104 uint64_t HubAdd; //48; uint8_t SlotLen; //3; uint16_t TimeSlots; //10; uint8_t Reserved; //1; uint8_t InterferenceMitigation; //1; uint8_t DutyCycling; //2; uint8_t DCHChannelNum; //6; uint8_t InitialState; //1; uint64_t TimeStamp; //32; }; struct MacHeader { struct FrameControl FrameCont; uint8_t RecipientID; uint8_t SenderID; uint8_t BanID; uint8_t FCS; }; struct MacFrame { struct MacHeader MacHeader; struct MacFrameBody MacBody; uint8_t FrameParity; }; //*****************************************************************************//Ack struct AckPacket { uint8_t len; struct MacHeader fAck; }; typedef struct AckPacket EasyLink_AckPacket; //*****************************************************************************//DownLink struct DownLinkFormat { uint8_t len; struct MacHeader fDownlink; uint16_t tPacket[20]; }; typedef struct DownLinkFormat EasyLink_DownLink; //*****************************************************************************//C-Ass(Total 168) struct CAssignmentFrameFormat { uint64_t RecAddr; //48; uint8_t NodeID; //8; uint16_t AssignedWakeupPhase; //16; uint16_t AssignedWakeupPeriod; //16; uint64_t UplinkAssignment; //40; uint64_t DownlinkAssignment; //40; }; struct CAssignmentFrame { uint8_t len; struct CAssignmentFrameFormat fCAss; }; typedef struct CAssignmentFrame EasyLink_CAss; //***************************************************************************** struct PacketHeader { uint8_t sourceAddress; uint8_t packetType; uint16_t sequencenum; }; struct testPacket //472 { struct PacketHeader header; //32 uint32_t timestamp; //32 uint8_t len; //8 unsigned int adc[5][100]; //400 }; typedef struct testPacket EasyLink_testPacket; //*****************************************************************************// //***************************** SmartBAN structure ****************************// //*****************************************************************************// typedef void (*EasyLink_CReceiveCb)(EasyLink_CReq rxPacket,EasyLink_Status status); typedef void (*EasyLink_CBReceiveCb)(EasyLink_CBeacon rxPacket,EasyLink_Status status); typedef void (*EasyLink_AReceiveCb)(EasyLink_AckPacket rxPacket,EasyLink_Status status); typedef void (*EasyLink_ReceiveCb)(EasyLink_RxPacket * rxPacket,EasyLink_Status status); typedef void (*EasyLink_DReceiveCb)(EasyLink_testPacket rxPacket,EasyLink_Status status); //typedef void (*EasyLink_ReceiveCb)(EasyLink_RxPacket * rxPacket,EasyLink_Status status); //! \brief EasyLink Callback function type for Received packet, registered with EasyLink_ReceiveAsync() typedef void (*EasyLink_TxDoneCb)(EasyLink_Status status); //! \brief EasyLink Callback function type for Tx Done registered with EasyLink_TransmitAsync() extern EasyLink_RfSetting EasyLink_supportedPhys[]; //! \brief Array containing all the supported EasyLink_rfSettings extern const uint8_t EasyLink_numSupportedPhys; //! \brief Size of the EasyLink_supportedPhys array extern void EasyLink_Params_init(EasyLink_Params *params); extern EasyLink_Status EasyLink_init(EasyLink_Params *params); extern EasyLink_Status EasyLink_getAbsTime(uint32_t *pui32AbsTime); extern EasyLink_Status EasyLink_getRssi(int8_t *pi8Rssi); extern EasyLink_Status EasyLink_transmit(EasyLink_TxPacket *txPacket); extern EasyLink_Status EasyLink_transmitAsync(EasyLink_TxPacket *txPacket,EasyLink_TxDoneCb cb); extern EasyLink_Status EasyLink_transmitCcaAsync(EasyLink_TxPacket *txPacket,EasyLink_TxDoneCb cb); extern EasyLink_Status EasyLink_receive(EasyLink_RxPacket *rxPacket); extern EasyLink_Status EasyLink_receiveAsync(EasyLink_ReceiveCb cb, uint32_t absTime); extern EasyLink_Status EasyLink_abort(void); extern EasyLink_Status EasyLink_setFrequency(uint32_t ui32Frequency); extern EasyLink_Status EasyLink_setFrequency_SET(uint32_t ui32Frequency); extern uint32_t EasyLink_getFrequency(void); extern EasyLink_Status EasyLink_enableRxAddrFilter(uint8_t* pui8AddrFilterTable,uint8_t ui8AddrSize, uint8_t ui8NumAddrs); extern EasyLink_Status EasyLink_getIeeeAddr(uint8_t *ieeeAddr); extern EasyLink_Status EasyLink_setRfPower(int8_t i8TxPowerDbm); extern EasyLink_Status EasyLink_getRfPower(int8_t *pi8TxPowerDbm); extern EasyLink_Status EasyLink_setCtrl(EasyLink_CtrlOption Ctrl,uint32_t ui32Value); extern EasyLink_Status EasyLink_getCtrl(EasyLink_CtrlOption Ctrl,uint32_t* pui32Value); extern EasyLink_Status EasyLink_transmit_CAss(EasyLink_CAss *txPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_transmit_Ack(EasyLink_AckPacket *txPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_transmit_DBeacon(EasyLink_DBeacon *txPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_transmit_CBeacon(EasyLink_CBeacon *txPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_transmit_DownLink(EasyLink_DownLink *txPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_receiveAsync_CBeacon(EasyLink_CBReceiveCb cb,EasyLink_CBeacon *txPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_receiveAsync_CReq(EasyLink_CReceiveCb cb,EasyLink_CReq *txPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_receiveAsync_Ack(EasyLink_AReceiveCb cb,EasyLink_AckPacket *rxPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_receiveAsync_Data(EasyLink_DReceiveCb cb,EasyLink_testPacket *rxPacket,EasyLink_TimeStamp TimeStamp); extern EasyLink_Status EasyLink_receiveAsync(EasyLink_ReceiveCb cb, uint32_t absTime); extern EasyLink_Status EasyLink_receive_CBeacon(EasyLink_CBeacon *rxPacket); extern EasyLink_Status EasyLink_receive_DBeacon(EasyLink_DBeacon *rxPacket); #ifdef __cplusplus } #endif #endif // Easylink__include