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.

CC1352P: Software enters Error_policyMin after call to RF_runCmd in a callback function

Part Number: CC1352P

Hello,

I just started on developing on the CC1352P1 kits and ran into a problem when executing the RF_runCmd in a button callback.

My starting point was the rfPacketTx example project (with TI-RTOS) where I simply copied the code for transmitting a packet into a button callback (I use the button driver app) and changed the frequency to 2.4 GHz. The RF_runCmd seems to execute well with the RF_EventLasCmdDone event and the PROP_DONE_OK command status and also my RX board receives the packet (indicated by the toggling LED). After this, the green LED is toggled, the radio is powered down and the core is set to sleep for 500 ms (these are all part of the rfPacketTx example code,).

After executing the button callback (including LED toggling, radio power down and sleep), the code runs into the GPIO_enableInt function but seems to fail when disabling the HWI (on HwiP_disable()). It then runs into the infinte loop of Error_policyMin().

Below you'll find the callstack.

And for further reference, here's my mainThread, (where I cut out seemingly unnecessary parts):

void *mainThread(void *arg0)
{
    RF_Params rfParams;
    RF_Params_init(&rfParams);

    /* Open LED pins */
    ledPinHandle = PIN_open(&ledPinState, pinTable);
    if (ledPinHandle == NULL)
    {
        while(1);
    }

    Button_Params  buttonParams;
    Button_init();
    logging_init(logLvlDebugLvl1);

    /* Open button 1 and button 2 */
    Button_Params_init(&buttonParams);
    buttonHandle[CONFIG_BUTTON_0] = Button_open(CONFIG_BUTTON_0,
                                              handleButtonCallback,
                                              &buttonParams);
    buttonHandle[CONFIG_BUTTON_1] = Button_open(CONFIG_BUTTON_1,
                                              handleButtonCallback,
                                              &buttonParams);

    /* Check if the button open is successful */
    if((buttonHandle[CONFIG_BUTTON_1]  == NULL) ||
        (buttonHandle[CONFIG_BUTTON_0]  == NULL))
    {
        while(1);
    }

    /* Create ring buffer to store button events */
    RingBuf_construct(&ringObj, eventBuf, EVENTBUFSIZE);

    RF_cmdPropTx_2msk250kbps_1.pktLen = PAYLOAD_LENGTH;
    RF_cmdPropTx_2msk250kbps_1.pPkt = packet;
    RF_cmdPropTx_2msk250kbps_1.startTrigger.triggerType = TRIG_NOW;

    /* 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_2msk250kbps_1, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup_2msk250kbps_1, &rfParams);
#endif// DeviceFamily_CC26X0R2

    /* Set the frequency */
    RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs_2msk250kbps_1, RF_PriorityNormal, NULL, 0);
    log_message(logMsgTypeInfo, "Frequency set to %d MHz", RF_cmdFs_2msk250kbps_1.frequency);

    RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx_2msk250kbps_1,
                                                       RF_PriorityNormal, NULL, 0);

    switch(terminationReason)
    {
        case RF_EventLastCmdDone:
            // A stand-alone radio operation command or the last radio
            // operation command in a chain finished.
            log_message(logMsgTypeDebugLvl1, "RF_runCmd return value: RF_EventLastCmdDone");
            break;
        .
        .
        .
        default:
            // Uncaught error event
            while(1);
    }

    uint32_t cmdStatus = ((volatile RF_Op*)&RF_cmdPropTx_2msk250kbps_1)->status;
    switch(cmdStatus)
    {
        case PROP_DONE_OK:
            // Packet transmitted successfully
            break;
        .
        .
        .
        default:
            // Uncaught error event - these could come from the
            // pool of states defined in rf_mailbox.h
            while(1);
    }

    while(1)
    {

    }
}


void handleButtonCallback(Button_Handle handle, Button_EventMask events)
{
    if(Button_EV_CLICKED == (events & Button_EV_CLICKED))
    {
        PIN_setOutputValue(ledPinHandle, CONFIG_PIN_GLED,!PIN_getOutputValue(CONFIG_PIN_GLED));


        /* Create packet with incrementing sequence number and random payload */
        packet[0] = (uint8_t)(seqNumber >> 8);
        packet[1] = (uint8_t)(seqNumber++);
        uint8_t i;
        for (i = 2; i < PAYLOAD_LENGTH; i++)
        {
            packet[i] = rand();
        }

        /* Send packet */
        RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx_2msk250kbps_1,
                                                   RF_PriorityNormal, NULL, 0);

        switch(terminationReason)
        {
            case RF_EventLastCmdDone:
                // A stand-alone radio operation command or the last radio
                // operation command in a chain finished.
                break;
            .
            .
            .
            default:
                // Uncaught error event
                while(1);
        }

        uint32_t cmdStatus = ((volatile RF_Op*)&RF_cmdPropTx_2msk250kbps_1)->status;
        switch(cmdStatus)
        {
            case PROP_DONE_OK:
                // Packet transmitted successfully
                break;
            .
            .
            .
            default:
                // Uncaught error event - these could come from the
                // pool of states defined in rf_mailbox.h
                while(1);
        }

#ifndef POWER_MEASUREMENT
        PIN_setOutputValue(ledPinHandle, CONFIG_PIN_GLED,!PIN_getOutputValue(CONFIG_PIN_GLED));
#endif
        /* Power down the radio */
        RF_yield(rfHandle);

#ifdef POWER_MEASUREMENT
        /* Sleep for PACKET_INTERVAL s */
        sleep(PACKET_INTERVAL);
#else
        /* Sleep for PACKET_INTERVAL us */
        usleep(PACKET_INTERVAL);
#endif
    }

Any help would be appreciated. If you need further detail, please let me know. Thank you in advance.

Sincerely,

Alex

  • Hi Alex,

    1) What version of the SimpleLink CC13xx/CC26xx SDK are you using?

    2) What is the purpose of the GPIO_enableInt() call you talk about? I can't see this API being called in the code snippet you posted?

    Cheers,

    Marie H

  • Hi Marie,

    Thank you very much for the fast reply.

    1) I'm using the SIMPLELINK-CC13X2-26X2-SDK_5.20.00.52

    2) I'll try to make it clearer what happens by going through step by step. The call to GPIO_enablieInt() is made by the button driver app in the file Button.c, see the code snippet below, included as an image so you can also see the line numbers for reference.


    The button driver calls my callback function in line 399, executes the code in my callback function and enters the GPIO_enableInt() function in GPIOCC26XX.c. In this function it calls the HwiP_disable function, which, I suppose, shall disable all interrupts before setting the GPIO interrupt.

    This function then calls Hwi_disable() in the source file HwiP_tirtos.c, as shown below.

     

    At this stage, the call stack looks like this:

    When I try to jump into the Hwi_disable function with the debugging probe, the debugger actually does not enter the function, but instead lets the code run. When I pause the debugger, I can see that it is stuck in the infinite loop of the Error_policyMin Error with the callstack I posted in my original post.

    Since this error does not occur when I comment out the RF_runCmd call in my callback function and instead toggle an LED, it works fine. So this is why this error is linked to my RF_runCmd call.

    Thank you.

    Greetings,

    Alex

  • Hi Alexander,

    There are a couple of things to check here.

    Can you use RF_runCmd() for your CMD_FS in line 48 instead of RF_postCmd(). 

    Run command is a combination of posting the command and waiting for the complete execution of the posted command. This ensures that CMD_FS is successful. 
    It is not adviced to use runCmd() in a callback for the same reason as mentioned above. It is a blocking action. Maybe you could post the command in the callback instead.

    This could possibly be some sort of a deadlock situation that you can avoid by posting the command in the callback.

    Regards,

    Sid