Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LAUNCHXL-CC2650: CC2650:How can get RSSI values.

Part Number: LAUNCHXL-CC2650
Other Parts Discussed in Thread: CC2650

Hi, I am creating a program to read RSSI values using CC2650.

I have two questions.

First, how do I read RSSI values?

I usually get the value using "lastRssi" in "EasyLink_receiveAsync", but I think I must receive something to use it.

If nothing is received, I can't get the RSSI value, and do I have to wait until receive anything?

Second, if nothing is received, I want to terminate "EasyLink_receiveAsync".

What should I do?

I used "EasyLink_cmdPropRxAdv.endTime" and "EasyLink_cmdPropRxAdv.endTrigger", but it didn't go next step.

Could someone please tell me?

Tatsuki

  • Hi Tatsuki,

    RSSI means "Received Signal Strength Indicator", implying that a signal must be received before this value can be measured.  You can pend on a sempahore and call EasyLink_abort to cancel Async operations after a pre-determined amount of time has passed.  I am using tirtos_cc13xx_cc26xx_2_21_01_08\examples\TI\CC2650_LAUNCHXL\rfEasyLinkRx\rfEasyLinkRx.c as an example:

            EasyLink_receiveAsync(rxDoneCb, 0);
    
            /* Wait 300ms for Rx */
            if(Semaphore_pend(rxDoneSem, (300000 / Clock_tickPeriod)) == FALSE)
            {
                /* RX timed out abort */
                if(EasyLink_abort() == EasyLink_Status_Success)
                {
                   /* Wait for the abort */
                   Semaphore_pend(rxDoneSem, BIOS_WAIT_FOREVER);
                }
            }

    Regards,
    Ryan

  • Hi Ryan,

    thanks for your reply!

    In fact, my program usually stopped at "EasyLink_receiveAsync_rssi".

    Where shuld I program the "Semaphore_pend" and "Easylnk_abort"?

    Please let me know.

    Tatsuki

    static void NodeFunction(UArg arg0, UArg arg1)
    {
            /* Start converting. */
            if (!adcBuf){System_abort("adcBuf did not open correctly\n");}
    
            while(i<37){
    
    
                    if(ReceiveAsync==1){
                        i+=1;
                        a+=1;
                        if(i==12)
                            i+=1;
    
                        /* frequency & Clock settings */
                        EasyLink_init(i);
                        ClockTime.EndTime=RF_getCurrentTime()+10*4000;
                    }
    
                    ReceiveAsync=0;
    
                    /*receive CBeacon*/
                    if(EasyLink_receiveAsync_rssi(ADVbit,ClockTime) != EasyLink_Status_Success)
                        {System_abort("EasyLink_receive_CBeacon failed");}
                    else ReceiveAsync=1;
    
                    rssi=ADVbit.rssi;
    
                    if(ReceiveAsync==1){
    
                    usprintf_mng("channel %d(%dMHz) : %d ",a,i*2+2402,rssi);
    
                    if(rssi>-40){
                        usprintf_mng("bad\n");
                        ChM_bitArray[b]|=1<<(7-i);
                    }
                    else {
                        usprintf_mng("good\n");
                        ChM_bitArray[b]|=0<<(7-i);
                    }
    
                    if(i%7==0)
                        b+=1;
    
                    usprintf_mng("\n");
                    }
            }
    

    //rxDoneCallback_rssi
    //*****************************************************************************//
    static void rxDoneCallback_rssi(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        EasyLink_ADVbit ADVbit;
        EasyLink_Status status = EasyLink_Status_Rx_Error;
    
        rfc_dataEntryGeneral_t *pDataEntry;
        pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer;
    
        Semaphore_post(busyMutex);
        asyncCmdHndl = EASYLINK_RF_CMD_HANDLE_INVALID;
    
    #if 1
        /*  Wait for 10ms for RX  */
        if(Semaphore_pend(busyMutex,(10000 / Clock_tickPeriod)) == FALSE){
            /*  RX timed out abort  */
            if(EasyLink_abort() == EasyLink_Status_Success){
                /*  wait for the abort  */
                Semaphore_pend(busyMutex,BIOS_WAIT_FOREVER);
            }
        }
    #endif
    
        if (e & RF_EventLastCmdDone)
        {
            if (EasyLink_cmdPropRxAdv.status == PROP_DONE_OK)
            {
                if (pDataEntry->status != DATA_ENTRY_FINISHED)
                {
                    status = EasyLink_Status_Rx_Error;
                    RF_flushCmd(h, RF_CMDHANDLE_FLUSH_ALL, 1);
                    usprintf_mng("E:%d\n",EasyLink_abort());
                }
                else if ( (rxStatistics.nRxOk == 1) ||
                         ((EasyLink_cmdPropRxAdv.pktConf.filterOp == 1) &&
                          (rxStatistics.nRxIgnored == 1)) )
                {
                    ADVbit.length = sizeof(ADVbit.ADV_bitArray);
                    memcpy(ADVbit.ADV_bitArray, (&pDataEntry->data+1), ADVbit.length);
                    ADVbit.rssi=rxStatistics.lastRssi;
                    status = EasyLink_Status_Success;
                }
                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;
                RF_flushCmd(h, RF_CMDHANDLE_FLUSH_ALL, 1);
                usprintf_mng("E:%d\n",EasyLink_abort());
                }
            }
            else if ( EasyLink_cmdPropRxAdv.status == PROP_DONE_RXTIMEOUT)
            {status = EasyLink_Status_Rx_Timeout;}
    
            else
            {status = EasyLink_Status_Rx_Error;
            RF_flushCmd(h, RF_CMDHANDLE_FLUSH_ALL, 1);
            usprintf_mng("E:%d\n",EasyLink_abort());
            }
    
        }
        else if ( (e == RF_EventCmdAborted) || e == RF_EventCmdStopped )
        {status = EasyLink_Status_Aborted;}
    
        if (ADVbitCb != NULL){ADVbitCb(ADVbit,status);}
        //usprintf_mng("Status:%d \n",status);
    }
    
    //EasyLink_receiveAsync_rssi
    //*****************************************************************************//
    EasyLink_Status EasyLink_receiveAsync_rssi(EasyLink_ADVbit cb,EasyLink_TimeStamp TimeStamp)
    {
    
        EasyLink_Status status = EasyLink_Status_Rx_Error;
        rfc_dataEntryGeneral_t *pDataEntry;
    
        if ( (!configured) || suspended)
        {return EasyLink_Status_Config_Error;}
    
        if (Semaphore_pend(busyMutex, 0) == FALSE)
        {return EasyLink_Status_Busy_Error;}
    
        //ADVbitCb = cb;
    
        pDataEntry = (rfc_dataEntryGeneral_t*) rxBuffer;
    
        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;
    
        EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME;
        EasyLink_cmdPropRxAdv.endTrigger.pastTrig = 1;
        EasyLink_cmdPropRxAdv.endTime = TimeStamp.EndTime;
    
        //Clear the Rx statistics structure
        memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t));
    
        asyncCmdHndl =RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,
                RF_PriorityNormal, rxDoneCallback_rssi, EASYLINK_RF_EVENT_MASK_RE);
    
        if (EasyLink_CmdHandle_isValid(asyncCmdHndl))
        {status = EasyLink_Status_Success;}
    
        return status;
    }
    

  • EasyLink_receiveAsync_rssi is not a function provided by the TI-RTOS package. EasyLink_receiveAsync is defined in tirtos_cc13xx_cc26xx_2_21_01_08\packages\examples\source\rf\easylink\EasyLink.c:

    EasyLink_Status EasyLink_receiveAsync(EasyLink_ReceiveCb cb, uint32_t absTime)
    {
        EasyLink_Status status = EasyLink_Status_Rx_Error;
        rfc_dataEntryGeneral_t *pDataEntry;
    
        //Check if not configure of already an Async command being performed
        if ( (!configured) || suspended)
        {
            return EasyLink_Status_Config_Error;
        }
        //Check and take the busyMutex
        if ( (Semaphore_pend(busyMutex, 0) == FALSE) || (EasyLink_CmdHandle_isValid(asyncCmdHndl)) )
        {
            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;
        }
        else
        {
            EasyLink_cmdPropRxAdv.startTrigger.triggerType = TRIG_NOW;
            EasyLink_cmdPropRxAdv.startTrigger.pastTrig = 1;
            EasyLink_cmdPropRxAdv.startTime = 0;
        }
    
        if (asyncRxTimeOut != 0)
        {
            EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_ABSTIME;
            EasyLink_cmdPropRxAdv.endTime = RF_getCurrentTime() + asyncRxTimeOut;
        }
        else
        {
            EasyLink_cmdPropRxAdv.endTrigger.triggerType = TRIG_NEVER;
            EasyLink_cmdPropRxAdv.endTime = 0;
        }
    
        //Clear the Rx statistics structure
        memset(&rxStatistics, 0, sizeof(rfc_propRxOutput_t));
    
        asyncCmdHndl = RF_postCmd(rfHandle, (RF_Op*)&EasyLink_cmdPropRxAdv,
                RF_PriorityNormal, rxDoneCallback, EASYLINK_RF_EVENT_MASK);
    
        if (EasyLink_CmdHandle_isValid(asyncCmdHndl))
        {
            status = EasyLink_Status_Success;
        }
    
        //busyMutex will be released in callback
    
        return status;
    }

    Since RF_postCmd is non-blocking, the return of this function should be immediate.  As shown in my earlier code excerpt, you should immediately pend upon completion of the RX command before continuing your code.  If the semaphore pend times out, then you would abort the RX command.

    Regards,
    Ryan

  • Hi Ryan,

    thanks for your reply!

    I want to continue reading rssi, but if nothing is received, my program stopped by System_abort.

    Sorry, this is mistake.

    Tatsuki.

                    /*receive CBeacon*/
                    if(EasyLink_receiveAsync_rssi(ADVbit,ClockTime) != EasyLink_Status_Success)
                        {System_abort("EasyLink_receive_CBeacon failed");}