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.

CCS/CC1310: Debugging EasyLink (porting LAUNCHXL-CC1310 to custom hardware)

Part Number: CC1310

Tool/software: Code Composer Studio

Hi,
I'm developing a wireless application based on the CC1310 launchpad, and a mix of the SimpleLink rfWsnNode, and concentrator TI-RTOS examples, along with some custom code.
I ported the hardware, then got most of my IO to work, and reached the point where I'm testing the RF part of the circuit, and ...  it does'nt work. Fine, this is not unexpected, and I wan't to continue to do some debugging.

What I'd like to do, and would love some help with, is:

  1. Set the sensitivity to a maximum (in order to have the EasyLink RX functions trigger even on noise)
    1. Why: I wan't  to verify that the internal RF circuit of the CC1310 is even running, and that I am able to break somewhere in the EasyLink RX functions.
    2. Questions: where do I define the sensitivity? Which functions of the EasyLink API would you suggest setting breakpoints inside (I've tried both `rxDoneCallback` and `EasyLink_receiveAsync` already)?

  2. Verify that my application can receive a packet, and filter based on the IEEE-address (lets talk about this when 1. is fulfilled)
  3. ... well, if 1. and 2. succeeds, I'm pretty much done . But I'd love to hear if you have any other debugging ideas?

I'm a bit worried that the error may be due to the 24 MHz crystal (don't know why, just a wild idea), so is there a way to verify that the internal RF circuitry is `running`?

Thanks!

  • Hi Rune

    To verify RF operation I would strongly recommend that you start with some simple RF examples, to see if you can get them up and running.

    Use the rfPacketRX and rfPacketTX example with defualt settings to make sure that you are able to establish a link. On the TX side you can step through the code, and after you run the C;D_PROP_TX command, you can look at the status od the command (RF_cmdPropTx.status) to see if the command run OK or not.

    On the RX side, you can set a breakpoint in the callback to see if you receive any packets.

    BR

    Siri

  • Hi Siri,

    Thanks for your reply :)!

    Just to be clear, everything worked on the launchpads, and I have only ported the receiving board, not the TX board which still runs untouched on the launchpad. I am also able to verify that packets are being sent using a SDR that I've got, so I am confident that my launchpad is TX'ing, but no RX functions are triggered on my custom hardware.

    • Where would you suggest putting the breakpoints on the RX side? I'm using the async RX functions, and as I've explained, I already tried `EasyLink_receiveAsync`.
    • Is there a way to detect if the RX circuitry is running/listening? eg. changing the sensitivity to have it trigger on noise alone

    Thanks,

    P.S.

    Your idea of starting from scratch with some simple RF examples is actually great advise, but I'd like this to be plan B--debugging existing firmware should be possible.

  • *isue not resolved*

  • I suggest that you make starting from scratch your plan A :-)

    You have already said that you have tested your SW on the LP and it is OK, so if your SW is OK, the problem is your HW, and there is no need to involve complex code to debug it.

    For both the rfPacketTX and rfPacketRX example it is easy to step through the code and verify that the different commands run OK (check the status field of each command in the debugger). You can also turn of all filtering/auto flushing and repeat mode, to make sure that if the device receives a sync word, data is received.

    Modify the rfPacketRX.c as shown below and set a watch on RF_cmdPropRadioSetup, RF_cmdFs and RF_cmdPropRx. Note that the setup and FS command are not executed before you call the RX command.

    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "Board.h"
    
    /* Application Header files */
    #include "RFQueue.h"
    #include "smartrf_settings/smartrf_settings.h"
    
    /***** Defines *****/
    
    /* Packet RX Configuration */
    #define DATA_ENTRY_HEADER_SIZE 8   /* Constant header size of a Generic Data Entry */
    #define MAX_LENGTH             255 /* Max length byte the radio will accept */
    #define NUM_DATA_ENTRIES       2   /* NOTE: Only two data entries supported at the moment */
    #define NUM_APPENDED_BYTES     2   /* The Data Entries data field will contain:
                                        * 1 Header byte (RF_cmdPropRx.rxConf.bIncludeHdr = 0x1)
                                        * Max 30 payload bytes
                                        * 1 status byte (RF_cmdPropRx.rxConf.bAppendStatus = 0x1) */
    
    
    
    /***** Prototypes *****/
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    /* Buffer which contains all Data Entries for receiving data.
     * Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__GNUC__)
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)]
                                                      __attribute__((aligned(4)));
    #else
    #error This compiler is not supported.
    #endif
    
    /* Receive dataQueue for RF Core to fill in data */
    static dataQueue_t dataQueue;
    static rfc_dataEntryGeneral_t* currentDataEntry;
    static uint8_t packetLength;
    static uint8_t* packetDataPointer;
    
    
    static uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] =
    {
        Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    	PIN_TERMINATE
    };
    
    /***** Function definitions *****/
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        if (ledPinHandle == NULL)
        {
            while(1);
        }
    
        if( RFQueue_defineQueue(&dataQueue,
                                rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer),
                                NUM_DATA_ENTRIES,
                                MAX_LENGTH + NUM_APPENDED_BYTES))
        {
            /* Failed to allocate space for all data entries */
            while(1);
        }
    
        /* Modify CMD_PROP_RX command for application needs */
        /* Set the Data Entity queue for received data */
        RF_cmdPropRx.pQueue = &dataQueue;
        /* Discard ignored packets from Rx queue */
        //RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
        /* Discard packets with CRC error from Rx queue */
        //RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
        RF_cmdPropRx.maxPktLen = MAX_LENGTH;
        //RF_cmdPropRx.pktConf.bRepeatOk = 1;
        //RF_cmdPropRx.pktConf.bRepeatNok = 1;
    
        /* Request access to the radio */
    #if defined(DeviceFamily_CC26X0R2)
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioSetup, &rfParams);
    #else
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    #endif// DeviceFamily_CC26X0R2
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        while(1)
        {
            /* Enter RX mode and stay forever in RX */
            RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx,
                                                        RF_PriorityNormal, &callback,
                                                        RF_EventRxEntryDone);
    
            switch(terminationReason)
            {
                case RF_EventLastCmdDone:
                    // A stand-alone radio operation command or the last radio
                    // operation command in a chain finished.
                    break;
                case RF_EventCmdCancelled:
                    // Command cancelled before it was started; it can be caused
                    // by RF_cancelCmd() or RF_flushCmd().
                    break;
                case RF_EventCmdAborted:
                    // Abrupt command termination caused by RF_cancelCmd() or
                    // RF_flushCmd().
                    break;
                case RF_EventCmdStopped:
                    // Graceful command termination caused by RF_cancelCmd() or
                    // RF_flushCmd().
                    break;
                default:
                    // Uncaught error event
                    while(1);
            }
    
            uint32_t cmdStatus = ((volatile RF_Op*)&RF_cmdPropRx)->status;
            switch(cmdStatus)
            {
                case PROP_DONE_OK:
                    // Packet received with CRC OK
                    break;
                case PROP_DONE_RXERR:
                    // Packet received with CRC error
                    break;
                case PROP_DONE_RXTIMEOUT:
                    // Observed end trigger while in sync search
                    break;
                case PROP_DONE_BREAK:
                    // Observed end trigger while receiving packet when the command is
                    // configured with endType set to 1
                    break;
                case PROP_DONE_ENDED:
                    // Received packet after having observed the end trigger; if the
                    // command is configured with endType set to 0, the end trigger
                    // will not terminate an ongoing reception
                    break;
                case PROP_DONE_STOPPED:
                    // received CMD_STOP after command started and, if sync found,
                    // packet is received
                    break;
                case PROP_DONE_ABORT:
                    // Received CMD_ABORT after command started
                    break;
                case PROP_ERROR_RXBUF:
                    // No RX buffer large enough for the received data available at
                    // the start of a packet
                    break;
                case PROP_ERROR_RXFULL:
                    // Out of RX buffer space during reception in a partial read
                    break;
                case PROP_ERROR_PAR:
                    // Observed illegal parameter
                    break;
                case PROP_ERROR_NO_SETUP:
                    // Command sent without setting up the radio in a supported
                    // mode using CMD_PROP_RADIO_SETUP or CMD_RADIO_SETUP
                    break;
                case PROP_ERROR_NO_FS:
                    // Command sent without the synthesizer being programmed
                    break;
                case PROP_ERROR_RXOVF:
                    // RX overflow observed during operation
                    break;
                default:
                    // Uncaught error event - these could come from the
                    // pool of states defined in rf_mailbox.h
                    while(1);
            }
        }
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventRxEntryDone)
        {
            /* Toggle pin to indicate RX */
            PIN_setOutputValue(ledPinHandle, Board_PIN_LED2,
                               !PIN_getOutputValue(Board_PIN_LED2));
    
            /* Get current unhandled data entry */
            currentDataEntry = RFQueue_getDataEntry();
    
            /* Handle the packet data, located at &currentDataEntry->data:
             * - Length is the first byte with the current configuration
             * - Data starts from the second byte */
            packetLength      = *(uint8_t*)(&currentDataEntry->data);
            packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);
    
            /* Copy the payload + the status byte to the packet variable */
            memcpy(packet, packetDataPointer, (packetLength + 1));
    
            RFQueue_nextEntry();
        }
    }

    Set a breakpoint on both

    switch(terminationReason)

    and

    if (e & RF_EventRxEntryDone).

    If you are not reaching any of these breakpoints, the radio is never finding sync.

    It is not possible to set the sensitivity of the board. The sensitivity is a measure of how weak a signal can be received, with a given BER or PER (Bit error Rate/Packet Error Rate), and is given in the data sheet for a specific HW + SW (register settings).

    For further debugging I recommend that you take a look at:


    You can also try to output the RX DATA on a pin and transmit a continuous preamble using SmartRF Studio, to see if you are able to recognize the preamble on the pin.

    How to do this is explained here:

    Siri

  • Hi Siri,

    I am in fact not reaching any of the breakpoints, I will investigate further during the next week. Thank you so much for your help up until now :).

    /Rune

  • I will close this thread for now, but please feel free to re-open if you have additional information/questions.

    BR

    Siri