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.

RTOS/LAUNCHXL-CC1310: Adding new button in the easyLinkTx

Part Number: LAUNCHXL-CC1310
Other Parts Discussed in Thread: SIMPLICITI

Tool/software: TI-RTOS

Hello

I've referenced the following thread 

It is partially helpful. I added two new buttons just like button 2 and 3. however, when i press the two buttons my packet is not being set. I believe this has to do with the internal pullups being in ON mode. i tried pin-setOutputEnable and setOutputValue but got many errors. my new button 2 and 3 is set to dio 29 and dio 30 respectively. i defined them in board.h and launchxl.h

the code works fine with button 0 and button 1. Kindly help me with how the dio 29 and 30 have to be initialized in order to send the packet.

  • Please post your code where the code you have added/ changed in the easyLinkTx example is highlighted.
  • //////////////////////////////////////////////////////////////////////////////BY SHUBHANKAR
    #define EMR_STOP   CC1310_LAUNCHXL_PIN_BTN3
    
    #define ON_OFF     CC1310_LAUNCHXL_PIN_BTN4
    //////////////////////////////////////////////////////////////////////////////BY SHUBHANKAR
    ///////////////////////////////////////////////////////////////////////////// BTN3 AND BTN4 HAVE BEEN DEFINED AS IOID29 AND IOID30 RESPECTIVELY
    
    PIN_Config pinTable[] = {
        Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    
    
    //SHUTDOWN WAKEUP
    /* Wake-up Button pin table */
    PIN_Config ButtonTableWakeUp[] = {
     //  Board_PIN_BUTTON0    | PIN_INPUT_EN | PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
      //  Board_PIN_BUTTON1     | PIN_INPUT_EN | PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
    
        EMR_STOP    | PIN_INPUT_EN | PIN_GPIO_HIGH | PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
        ON_OFF     | PIN_INPUT_EN | PIN_GPIO_HIGH| PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
        PIN_TERMINATE                                 /* Terminate list */
    };
    
    
    if ((PIN_getInputValue(EMR_STOP))==0) {
                PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
                PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
                for (i = 2; i < RFEASYLINKTXPAYLOAD_LENGTH; i++)
                {
                    txPacket.payload[i] = 0x01;
                }
                // Set Tx absolute time to current time + 100ms
                txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1);
                sendPacketTrigger = 1;
            }
    
    
            else if (PIN_getInputValue(ON_OFF)==0) {
                PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
                PIN_setOutputValue(pinHandle, Board_PIN_LED2, 1);
                for (i = 2; i < RFEASYLINKTXPAYLOAD_LENGTH; i++)
                {
                    txPacket.payload[i] = 0x02;
                }
                // Set Tx absolute time to current time + 100ms
                txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1);
                sendPacketTrigger = 1;
            }

    So i have two external buttons namely ON_OFF and EMR_STOP. these are set to pullup. However, when i begin debugging, without checking for the condition EMR_STOP/ON_OFF==0 (button pressed), the loop enters and switches on the green led and while pressing the button no packet is sent.

    the low power mode works perfectly. i tried to check by using the on board btn1 and btn2 and it was working.

    EMR_STOP and ON_OFF have been defined as pin 29 and 30 on the launchpad. could that be a problem since they are also analog pins? I tried changing to pin 10,12 but it still didn't work. i have a doubt with the pin.h file wherein all the settings are made for the pins as input/output.

    Thanks TER!

  • Why do you set up the pins as PINCC26XX_WAKEUP_NEGEDGE? Look into using PIN_IRQ_NEGEDGE and a call back function that is run when a button is pressed instead of polling the pin. PIN_IRQ_NEGEDGE is used in some of the examples in the SDK.
  • Hi TER

    Thanks for the reply. I'll change it to Interrupt request. However PIN_IRQ_NEGEDGE is defined as PIN_GEN|(0x5<<16)
    Does this mean that it is applied only to the DIOs 5 through 16? THere shouldn't be a problem with pin 29 and 30 since they are analog capable and i am using it for digital purpose right?

    Also, how and where do i define the callback function? Wont the simple if-loop as in the above case do?
  • I believe the PIN_GEN|(0x5<<16) is setting the bit enabling interrupt in the IOCFG registers.

    If you look at the rfPacketErrorRate.c file in the example with the same name you find an example on callback. Regardless of method you should implement some sort of debounce.
  • Hi TER

    Thanks for that point. In the rfPacketErrorRate.c, i see a button callback f'n implemented with the debounce, so should i replace the entire code from line 27 to 50 with the call back function? Also, previously i found that the code was entering into the if loop without even checking the button press event with the external buttons EMR_STOP and ON_OFF, but with the on board buttons it worked fine.

    How does the IRQ_NEGEDGE and debounce influence the change?

  • Hi TER,

    My buttons are working and the receiver is also receiving the packets. however, I require my transmitter to be in sleep mode (~7 uA) while it is not transmitting via button press

    I am attaching my code here. when i uncomment Power_shutdown(0,0) ,try to place my code in the else loop etc. the same old problem of the pins getting bypassed and the leds coming on happens. can you suggest a solution for the same?

    void txDoneCb(EasyLink_Status status)
    {
    
        Semaphore_post(txDoneSem);
    }
    #endif //RFEASYLINKTX_ASYNC
    
    
    
    
    static void buttonCallbackFunction(PIN_Handle handle, PIN_Id pinId)
    {
        //uint8_t txBurstSize = 0;
            uint8_t cntr = 0;
        #ifdef RFEASYLINKTX_ASYNC
            /* Create a semaphore for Async */
            Semaphore_Params params;
            Error_Block eb;
    
            /* Init params */
            Semaphore_Params_init(&params);
            Error_init(&eb);
    
            /* Create semaphore instance */
            txDoneSem = Semaphore_create(0, &params, &eb);
        #endif //TX_ASYNC
    
            EasyLink_init(EasyLink_Phy_Custom);
    
            /* Set output power to 12dBm */
            EasyLink_setRfPwr(10);
    
            while(1) {
           // while(cntr<1) {
    
    
                EasyLink_TxPacket txPacket =  { {0}, 0, 0, {0} };
                txPacket.payload[0] = (uint8_t)(seqNumber >> 8);
                txPacket.payload[1] = (uint8_t)(seqNumber++);
    
    
                txPacket.len = RFEASYLINKTXPAYLOAD_LENGTH;
                txPacket.dstAddr[0] = 0xaa;
                uint8_t i, sendPacketTrigger = 0;
    
                /* Simple debounce logic, only toggle if the button is still pushed (low) */
                //   CPUdelay((uint32_t)((48000000/3)*0.050f));
                      int myPin = PIN_getInputValue(PIN_ID(29));
                       if (myPin ==0)
                       {
                           CPUdelay((uint32_t)((48000000/3)*0.050f));
                          // if(myPin==1)
                       //{
                          // menu_notifyButtonPressed(Button_Navigate);
                           PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
                                      PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
                                      for (i = 2; i < RFEASYLINKTXPAYLOAD_LENGTH; i++)
                                      {
                                          txPacket.payload[i] = 0x01;
                                      }
                                      // Set Tx absolute time to current time + 100ms
                                      txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1);
                                      sendPacketTrigger = 1;
                       }
    
                       else if (PIN_getInputValue(Board_PIN_BUTTON1)==0)
                       {
                           CPUdelay((uint32_t)((48000000/3)*0.050f));
                           // menu_notifyButtonPressed(Button_Select);
                          PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
                                     PIN_setOutputValue(pinHandle, Board_PIN_LED2, 1);
                                      for (i = 2; i < RFEASYLINKTXPAYLOAD_LENGTH; i++)
                                      {
                                          txPacket.payload[i] = 0x02;
                                      }
                                      // Set Tx absolute time to current time + 100ms
                                      txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1);
                                      sendPacketTrigger = 1;
                      }
                       else{
                              PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
                              PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
                              sendPacketTrigger = 0;
                              cntr++;
    
                          }
    
                          if(sendPacketTrigger == 1)
                          {
                              EasyLink_transmitAsync(&txPacket, txDoneCb);
                              // Wait 300ms for Tx to complete
                              if(Semaphore_pend(txDoneSem, (300000 / Clock_tickPeriod)) == FALSE)
                              {
                                  // TX timed out, abort
                                  if(EasyLink_abort() == EasyLink_Status_Success)
                                  {
    
                                     Semaphore_pend(txDoneSem, BIOS_WAIT_FOREVER);
                                  }
                              }
                              sendPacketTrigger = 0;
                              cntr = 0;
    
                          }
    
    
    
                      cntr = 0;
                     // Power_shutdown(0, 0);
                      // Configure DIO for wake up from shutdown
                      PINCC26XX_setWakeup(ButtonTableWakeUp);
    
                      // Go to shutdown
                      //Power_shutdown(0, 0);
    
                      // Should never get here, since shutdown will reset.
                     // while(1);
    
                  //}
            }
    }
    
    void txTask_init(PIN_Handle inPinHandle) {
        pinHandle = inPinHandle;
    
        Task_Params_init(&txTaskParams);
        txTaskParams.stackSize = RFEASYLINKTX_TASK_STACK_SIZE;
        txTaskParams.priority = RFEASYLINKTX_TASK_PRIORITY;
        txTaskParams.stack = &txTaskStack;
        txTaskParams.arg0 = (UInt)1000000;
    
      //  Task_construct(&txTask, rfEasyLinkTxFnx, &txTaskParams, NULL);
        Task_construct(&txTask, buttonCallbackFunction, &txTaskParams, NULL);
    }
    
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call driver init functions. */
        Board_initGeneral();
    
        /* Open LED pins */
        pinHandle = PIN_open(&pinState, pinTable);
        if(!pinHandle) {
            System_abort("Error initializing board LED pins\n");
        }
    
        /* Clear LED pins */
        PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
        PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
    
        txTask_init(pinHandle);
        ///////////////////////////////////////////////////////////////////////////////////////ADDED BY SHUBHANKAR
        PIN_Status status = PIN_registerIntCb(buttonPinHandle, &buttonCallbackFunction);
        /////////////////////////////////////////////////////////////////////////////////BY SHUBHANKAR
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }

  • If you go to shutdown you most likely have to reconfigure the pins when you wake up again. See the pinshutdown example how this is done here.
  • Hi TER

    Could you elaborate on that please? I turned off the external flash on the launchpad  but i still get around 4 mA in sleep.

    can i add the pinShutdown.c in a separate folder in my easylink, delete the redundancy parts and get it to work? 

  • I suspect that I need to look at this from a different angle (write some code myself) What exactly do you want the two buttons to do?
  • Hey TER

    I interfaced pinShutdown.c in a separate folder of the rfEasyLinkTx project

    Both the buttons have to just send a packet '01' and '02' respectively when pressed after which the controller should be in shutdown mode to minimize batt consumption.

    That is the application in one line. Buttons work fine. I get my packets on the rx side. however, the device is not sleeping (6mA while not txing)

    Thanks

    Shubhankar

  • Forgot to ask: You are checking the power consumption without the debugger connected I assume?
  • Hi ter

    Sorry i clicked resolved by mistake

    Yes everything was disconnected, including led jumpers to minimize consumption.
  • Hello TER,

    I'd like to state that my issue is still not resolved. that was a mistake :P

  • Sorry, didn't have the time to look at it yesterday. At the moment the code goes to shutdown after the first press on the button but it doesn't go to TX the second time. I have to do some more debugging.
  • /*
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== rfEasyLinkTx.c ========
     */
     /* Standard C Libraries */
    #include <stdlib.h>
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/Assert.h>
    #include <xdc/runtime/Error.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/Clock.h>
    #include <ti/sysbios/posix/unistd.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    
    #include DeviceFamily_constructPath(inc/hw_prcm.h)
    #include DeviceFamily_constructPath(driverlib/sys_ctrl.h)
    
    /* Board Header files */
    #include "Board.h"
    
    /* EasyLink API Header files */
    #include "easylink/EasyLink.h"
    
    /* Undefine to not use async mode */
    #define RFEASYLINKTX_ASYNC
    
    #define RFEASYLINKTX_TASK_STACK_SIZE    1024
    #define RFEASYLINKTX_TASK_PRIORITY      2
    
    #define RFEASYLINKTX_BURST_SIZE         10
    #define RFEASYLINKTXPAYLOAD_LENGTH      30
    
    Task_Struct txTask;    /* not static so you can see in ROV */
    static Task_Params txTaskParams;
    static uint8_t txTaskStack[RFEASYLINKTX_TASK_STACK_SIZE];
    
    /* Pin driver handle */
    static PIN_Handle pinHandle;
    static PIN_State pinState;
    
    /* PIN_Id for active button (in debounce period) */
    PIN_Id activeButtonPinId;
    
    /* Wake-up Button pin table */
    PIN_Config ButtonTableWakeUp[] = {
        Board_PIN_BUTTON0     | PIN_INPUT_EN | PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
        PIN_TERMINATE                                 /* Terminate list */
    };
    
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] = {
        Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #if defined __CC1352R1_LAUNCHXL_BOARD_H__
        Board_DIO30_RFSW | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #endif    
    	PIN_TERMINATE
    };
    
    
    static uint16_t seqNumber;
    
    #ifdef RFEASYLINKTX_ASYNC
    static Semaphore_Handle txDoneSem;
    #endif //RFEASYLINKTX_ASYNC
    
    #ifdef RFEASYLINKTX_ASYNC
    void txDoneCb(EasyLink_Status status)
    {
        if (status == EasyLink_Status_Success)
        {
            /* Toggle LED1 to indicate TX */
            //PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
        }
        else if(status == EasyLink_Status_Aborted)
        {
            /* Toggle LED2 to indicate command aborted */
            //PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
        }
        else
        {
            /* Toggle LED1 and LED2 to indicate error */
            //PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
            //PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
        }
    
        Semaphore_post(txDoneSem);
    }
    #endif //RFEASYLINKTX_ASYNC
    
    static void rfEasyLinkTxFnx(UArg arg0, UArg arg1)
    {
        uint8_t txBurstSize = 0;
    
    #ifdef RFEASYLINKTX_ASYNC
        /* Create a semaphore for Async */
        Semaphore_Params params;
        Error_Block eb;
    
        /* Init params */
        Semaphore_Params_init(&params);
        Error_init(&eb);
    
        /* Create semaphore instance */
        txDoneSem = Semaphore_create(0, &params, &eb);
    #endif //TX_ASYNC
    
        PIN_setOutputValue(pinHandle, Board_PIN_LED2, 1);
        EasyLink_init(EasyLink_Phy_Custom);
    
        /*
         * If you wish to use a frequency other than the default, use
         * the following API:
         * EasyLink_setFrequency(868000000);
         */
    
        /* Set output power to 12dBm */
        EasyLink_setRfPwr(12);
    
    
        EasyLink_TxPacket txPacket =  { {0}, 0, 0, {0} };
         /* Create packet with incrementing sequence number and random payload */
        txPacket.payload[0] = (uint8_t)(seqNumber >> 8);
        txPacket.payload[1] = (uint8_t)(seqNumber++);
        uint8_t i;
        for (i = 2; i < RFEASYLINKTXPAYLOAD_LENGTH; i++)
        {
          txPacket.payload[i] = rand();
        }
    
        txPacket.len = RFEASYLINKTXPAYLOAD_LENGTH;
        txPacket.dstAddr[0] = 0xaa;
    
        /* Add a Tx delay for > 500ms, so that the abort kicks in and brakes the burst */
        if(txBurstSize++ >= RFEASYLINKTX_BURST_SIZE)
        {
            /* Set Tx absolute time to current time + 1s */
            txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1000);
            txBurstSize = 0;
         }
         /* Else set the next packet in burst to Tx in 100ms */
         else
         {
            /* Set Tx absolute time to current time + 100ms */
            txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(100);
         }
    
            EasyLink_transmitAsync(&txPacket, txDoneCb);
            /* Wait 300ms for Tx to complete */
            if(Semaphore_pend(txDoneSem, (300000 / Clock_tickPeriod)) == FALSE)
            {
                /* TX timed out, abort */
                if(EasyLink_abort() == EasyLink_Status_Success)
                {
                    /*
                     * Abort will cause the txDoneCb to be called and the txDoneSem
                     * to be released, so we must consume the txDoneSem
                     */
                   Semaphore_pend(txDoneSem, BIOS_WAIT_FOREVER);
                }
            }
            /* Go to shutdown */
    
            PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
            PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
    
            Power_shutdown(0, 0);
    }
    
    void txTask_init(PIN_Handle inPinHandle) {
        pinHandle = inPinHandle;
    
        Task_Params_init(&txTaskParams);
        txTaskParams.stackSize = RFEASYLINKTX_TASK_STACK_SIZE;
        txTaskParams.priority = RFEASYLINKTX_TASK_PRIORITY;
        txTaskParams.stack = &txTaskStack;
        txTaskParams.arg0 = (UInt)1000000;
    
        Task_construct(&txTask, rfEasyLinkTxFnx, &txTaskParams, NULL);
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call driver init functions. */
        Board_initGeneral();
    
        Board_shutDownExtFlash();
    
        /* Open LED pins */
        pinHandle = PIN_open(&pinState, pinTable);
    	Assert_isTrue(pinHandle != NULL, NULL); 
    
    	/* Configure DIO for wake up from shutdown */
    	PINCC26XX_setWakeup(ButtonTableWakeUp);
    
        /* Clear LED pins */
        PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
        //PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
    
        txTask_init(pinHandle);
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    

    The attached code send one packet and goes down in shutdown. In this code the button does not have any debounce logic and it should have some to avoid sending more than one packet after pushing the button. The code does not contain any callback function for the button since the only thing happening is sebding a random packet and go down in shutdown again.

    Note that a function to turn off the external flash is included since if this is not done the flash will draw ~8 uA

     

  • Hey TER

    Thank you very much for this code. How was it different from the one in the example i referenced (at the start of this thread). and you declared the button as a negedge shouldn't it be PIN_IRQ? i'm using two external buttons not the launchpad ones

  • Hey TER

    I wanted to know where i had to keep the button press and theri debounce logic. The buttons are supposed to send packet 01 and 02 respectively because they are meant to do different f'ns at the Rx side

    /*
     *  ======== rfEasyLinkTx.c ========
     */
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/Assert.h>
    #include <xdc/runtime/Error.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/Clock.h>
    #include <ti/sysbios/posix/unistd.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    
    #include DeviceFamily_constructPath(inc/hw_prcm.h)
    #include DeviceFamily_constructPath(driverlib/sys_ctrl.h)
    
    
    
    /* Board Header files */
    #include "Board.h"
    
    /* EasyLink API Header files */
    #include "easylink/EasyLink.h"
    
    //////////////////////////////////////////////////////////////////////////////BY SHUBHANKAR
    #define EMR_STOP   CC1310_LAUNCHXL_PIN_BTN3
    
    #define ON_OFF     CC1310_LAUNCHXL_PIN_BTN4
    
    #define EMR 01
    #define ONOFF 02
    
    
    PIN_Handle buttonPinHandle;
    //////////////////////////////////////////////////////////////////////////////BY SHUBHANKAR
    
    #define RFEASYLINKTX_ASYNC
    
    #define RFEASYLINKTX_TASK_STACK_SIZE    1024
    #define RFEASYLINKTX_TASK_PRIORITY      2
    
    #define RFEASYLINKTX_BURST_SIZE         10
    #define RFEASYLINKTXPAYLOAD_LENGTH      30
    
    Task_Struct txTask;    /* not static so you can see in ROV */
    static Task_Params txTaskParams;
    static uint8_t txTaskStack[RFEASYLINKTX_TASK_STACK_SIZE];
    
    /* Pin driver handle */
    static PIN_Handle pinHandle;
    static PIN_State pinState;
    
    /* PIN_Id for active button (in debounce period) */
    PIN_Id activeButtonPinId;
    
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] = {
        Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    
    
    //SHUTDOWN WAKEUP
    /* Wake-up Button pin table */
    PIN_Config ButtonTableWakeUp[] = {
                                       ///////////////////////////////////////////////////////////////////////////////////////ALL CHANGES BY SHUBHANKAR
    //   Board_PIN_BUTTON0    | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,                             // was previously PINCC26XX_WAKEUP_NEGEDGE,
      //  Board_PIN_BUTTON0     | PIN_INPUT_EN | PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
        EMR_STOP    | PIN_INPUT_EN | PIN_GPIO_LOW | PIN_PULLUP | PIN_IRQ_NEGEDGE,
          ON_OFF     | PIN_INPUT_EN | PIN_GPIO_LOW| PIN_PULLUP | PIN_IRQ_NEGEDGE,
        PIN_TERMINATE
        /* Terminate list */
    };
    
    
    static uint16_t seqNumber;
    
    #ifdef RFEASYLINKTX_ASYNC
    static Semaphore_Handle txDoneSem;
    #endif //RFEASYLINKTX_ASYNC
    
    #ifdef RFEASYLINKTX_ASYNC
    void txDoneCb(EasyLink_Status status)
    {
        if (status == EasyLink_Status_Success)
        {
            /* Toggle LED1 to indicate TX */
            PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
        }
        else if(status == EasyLink_Status_Aborted)
        {
            /* Toggle LED2 to indicate command aborted */
            PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
        }
        else
        {
            /* Toggle LED1 and LED2 to indicate error */
            PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
            PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
        }
    
        Semaphore_post(txDoneSem);
    }
    #endif //RFEASYLINKTX_ASYNC
    
    
    static void rfEasyLinkTxFnx(UArg arg0, UArg arg1)
    {
    
        uint8_t txBurstSize = 0;
    
                #ifdef RFEASYLINKTX_ASYNC
                    /* Create a semaphore for Async */
                    Semaphore_Params params;
                    Error_Block eb;
    
                    /* Init params */
                    Semaphore_Params_init(&params);
                    Error_init(&eb);
    
                    /* Create semaphore instance */
                    txDoneSem = Semaphore_create(0, &params, &eb);
                #endif //TX_ASYNC
    
                    PIN_setOutputValue(pinHandle, Board_PIN_LED2, 1);
                    EasyLink_init(EasyLink_Phy_Custom);
    
    
                     /* If you wish to use a frequency other than the default, use
                     * the following API:
                      EasyLink_setFrequency(868000000);
                     */
                    EasyLink_setFrequency(434000000);
                    /* Set output power to 12dBm */
                    EasyLink_setRfPwr(12);
    
                 /////////////////////////////////////////////////////////////////////////////////////////////CORE CODE BEGINS HERE
                    EasyLink_TxPacket txPacket =  { {0}, 0, 0, {0} };
                                 /* Create packet with incrementing sequence number and random payload */
                                txPacket.payload[0] = (uint8_t)(seqNumber >> 8);
                                txPacket.payload[1] = (uint8_t)(seqNumber++);
                                uint8_t i;
                                txPacket.len = RFEASYLINKTXPAYLOAD_LENGTH;
                                                            txPacket.dstAddr[0] = 0xaa;
    
            while(1) {
          
    //////////////////////////////////////////////////////////////////////////////////////////////////////EMR_STOP BUTTON
                    CPUdelay((uint32_t)((48000000/3)*0.050f));
    
                    if (PIN_getInputValue(PIN_ID(29))==0)
                   {
                    CPUdelay((uint32_t)((48000000/3)*0.050f));//////////////////////////////////////////////////////////for debounce
                    PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
                   PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
                for (i = 2; i < RFEASYLINKTXPAYLOAD_LENGTH; i++)
                {
                  txPacket.payload[i] = EMR;
                }
    
               // txPacket.len = RFEASYLINKTXPAYLOAD_LENGTH;
               // txPacket.dstAddr[0] = 0xaa;
                txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1);
                   }
    
    
     ///////////////////////////////////////////////////////////////////////////////////////////////////////////////ON_OFF SWITCH
    
                    else if(PIN_getInputValue(PIN_ID(30))==0)
                    {
                        CPUdelay((uint32_t)((48000000/3)*0.050f));  //////////////////////////////////////for debounce logic
                                       PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
                                      PIN_setOutputValue(pinHandle, Board_PIN_LED2, 1);
                                   for (i = 2; i < RFEASYLINKTXPAYLOAD_LENGTH; i++)
                                   {
                                     txPacket.payload[i] = ONOFF;
                                   }
    
    
                                   txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1);
                                      }
    
                /* Add a Tx delay for > 500ms, so that the abort kicks in and brakes the burst */
                //if(txBurstSize++ >= RFEASYLINKTX_BURST_SIZE)
               // {
                    /* Set Tx absolute time to current time + 1s */
                  //  txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1); /////////////////changed radiotime to 1 from 1000
                 //   txBurstSize = 0;
                // }
                 /* Else set the next packet in burst to Tx in 100ms */
                // else
                // {
                    /* Set Tx absolute time to current time + 100ms */
                  //  txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(100);
                // }
    
                    EasyLink_transmitAsync(&txPacket, txDoneCb);
                    /* Wait 300ms for Tx to complete */
                    if(Semaphore_pend(txDoneSem, (300000 / Clock_tickPeriod)) == FALSE)
                    {
                        /* TX timed out, abort */
                        if(EasyLink_abort() == EasyLink_Status_Success)
                        {
                            /*
                             * Abort will cause the txDoneCb to be called and the txDoneSem
                             * to be released, so we must consume the txDoneSem
                             */
                           Semaphore_pend(txDoneSem, BIOS_WAIT_FOREVER);
                        }
                    }
                    PINCC26XX_setWakeup(ButtonTableWakeUp);
                    /* Go to shutdown */
    
                    PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
                    PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
    
                    Power_shutdown(0, 0);
            }
    }
    
    void txTask_init(PIN_Handle inPinHandle) {
        pinHandle = inPinHandle;
    
        Task_Params_init(&txTaskParams);
        txTaskParams.stackSize = RFEASYLINKTX_TASK_STACK_SIZE;
        txTaskParams.priority = RFEASYLINKTX_TASK_PRIORITY;
        txTaskParams.stack = &txTaskStack;
        txTaskParams.arg0 = (UInt)1000000;
    
        Task_construct(&txTask, rfEasyLinkTxFnx, &txTaskParams, NULL);
    }
    
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call driver init functions. */
       Board_initGeneral();
    
       Board_shutDownExtFlash();
    
           /* Open LED pins */
           pinHandle = PIN_open(&pinState, pinTable);
           Assert_isTrue(pinHandle != NULL, NULL);
    
    
        /* Clear LED pins */
        PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
        PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
    
        txTask_init(pinHandle);
        ///////////////////////////////////////////////////////////////////////////////////////ADDED BY SHUBHANKAR
       // PIN_Status status = PIN_registerIntCb(buttonPinHandle, &taskFxn);
        /////////////////////////////////////////////////////////////////////////////////BY SHUBHANKAR
    
       // main_app();
        /* Start BIOS */
       BIOS_start();
    
        return (0);
    }
    

    I moved your code here and there to suit the button operation. Also i used the two buttons as irq_negedge as you suggested earlier. your code just sends out one packet, so i put the whole thing in a while(1)

    However, in my code the packet isn't being sent anymore when either of the two buttons are pressed. Help me out here please!

  • /*
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== rfEasyLinkTx.c ========
     */
     /* Standard C Libraries */
    #include <stdlib.h>
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/Assert.h>
    #include <xdc/runtime/Error.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/Clock.h>
    #include <ti/sysbios/posix/unistd.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26XX.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    
    #include DeviceFamily_constructPath(inc/hw_prcm.h)
    #include DeviceFamily_constructPath(driverlib/sys_ctrl.h)
    
    /* Board Header files */
    #include "Board.h"
    
    /* EasyLink API Header files */
    #include "easylink/EasyLink.h"
    
    /* Undefine to not use async mode */
    #define RFEASYLINKTX_ASYNC
    
    #define RFEASYLINKTX_TASK_STACK_SIZE    1024
    #define RFEASYLINKTX_TASK_PRIORITY      2
    
    #define RFEASYLINKTX_BURST_SIZE         10
    #define RFEASYLINKTXPAYLOAD_LENGTH      30
    
    Task_Struct txTask;    /* not static so you can see in ROV */
    static Task_Params txTaskParams;
    static uint8_t txTaskStack[RFEASYLINKTX_TASK_STACK_SIZE];
    
    /* Pin driver handle */
    static PIN_Handle pinHandle;
    static PIN_State pinState;
    
    
    PIN_Handle hButtons;
    
    Semaphore_Struct but1_Sem;
    Semaphore_Struct but2_Sem;
    
    /* Clock used for debounce logic */
    Clock_Struct buttonClock;
    Clock_Handle hButtonClock;
    
    PIN_Handle buttonHandle;
    
    /* PIN_Id for active button (in debounce period) */
    PIN_Id activeButtonPinId;
    
    PIN_State buttonStateDetect;
    
    /* Wake-up Button pin table */
    PIN_Config ButtonTableWakeUp[] = {
        Board_PIN_BUTTON0     | PIN_INPUT_EN | PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
        Board_PIN_BUTTON1     | PIN_INPUT_EN | PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
        PIN_TERMINATE                                 /* Terminate list */
    };
    
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] = {
        Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #if defined __CC1352R1_LAUNCHXL_BOARD_H__
        Board_DIO30_RFSW | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #endif    
    	PIN_TERMINATE
    };
    
    
    static uint16_t seqNumber;
    
    #ifdef RFEASYLINKTX_ASYNC
    static Semaphore_Handle txDoneSem;
    #endif //RFEASYLINKTX_ASYNC
    
    #ifdef RFEASYLINKTX_ASYNC
    void txDoneCb(EasyLink_Status status)
    {
        if (status == EasyLink_Status_Success)
        {
            /* Toggle LED1 to indicate TX */
            //PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
        }
        else if(status == EasyLink_Status_Aborted)
        {
            /* Toggle LED2 to indicate command aborted */
            //PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
        }
        else
        {
            /* Toggle LED1 and LED2 to indicate error */
            //PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
            //PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
        }
    
        Semaphore_post(txDoneSem);
    }
    #endif //RFEASYLINKTX_ASYNC
    
    static void rfEasyLinkTxFnx(UArg arg0, UArg arg1)
    {
        uint8_t txBurstSize = 0;
    
    #ifdef RFEASYLINKTX_ASYNC
        /* Create a semaphore for Async */
        Semaphore_Params params;
        Error_Block eb;
    
        /* Init params */
        Semaphore_Params_init(&params);
        Error_init(&eb);
    
        /* Create semaphore instance */
        txDoneSem = Semaphore_create(0, &params, &eb);
    #endif //TX_ASYNC
    
        /* Pend on semaphore before going to shutdown */
        Semaphore_pend(Semaphore_handle(&but1_Sem), BIOS_WAIT_FOREVER);
    
        PIN_setOutputValue(pinHandle, Board_PIN_LED2, 1);
        EasyLink_init(EasyLink_Phy_Custom);
    
        /*
         * If you wish to use a frequency other than the default, use
         * the following API:
         * EasyLink_setFrequency(868000000);
         */
    
        /* Set output power to 12dBm */
        EasyLink_setRfPwr(12);
    
    
        EasyLink_TxPacket txPacket =  { {0}, 0, 0, {0} };
         /* Create packet with incrementing sequence number and random payload */
        txPacket.payload[0] = (uint8_t)(seqNumber >> 8);
        txPacket.payload[1] = (uint8_t)(seqNumber++);
        uint8_t i;
        for (i = 2; i < RFEASYLINKTXPAYLOAD_LENGTH; i++)
        {
          txPacket.payload[i] = rand();
        }
    
        txPacket.len = RFEASYLINKTXPAYLOAD_LENGTH;
        txPacket.dstAddr[0] = 0xaa;
    
        /* Add a Tx delay for > 500ms, so that the abort kicks in and brakes the burst */
        if(txBurstSize++ >= RFEASYLINKTX_BURST_SIZE)
        {
            /* Set Tx absolute time to current time + 1s */
            txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(1000);
            txBurstSize = 0;
         }
         /* Else set the next packet in burst to Tx in 100ms */
         else
         {
            /* Set Tx absolute time to current time + 100ms */
            txPacket.absTime = EasyLink_getAbsTime() + EasyLink_ms_To_RadioTime(100);
         }
    
            EasyLink_transmitAsync(&txPacket, txDoneCb);
            /* Wait 300ms for Tx to complete */
            if(Semaphore_pend(txDoneSem, (300000 / Clock_tickPeriod)) == FALSE)
            {
                /* TX timed out, abort */
                if(EasyLink_abort() == EasyLink_Status_Success)
                {
                    /*
                     * Abort will cause the txDoneCb to be called and the txDoneSem
                     * to be released, so we must consume the txDoneSem
                     */
                   Semaphore_pend(txDoneSem, BIOS_WAIT_FOREVER);
                }
            }
            /* Go to shutdown */
    
            PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
            PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
    
            Power_shutdown(0, 0);
    }
    
    void txTask_init(PIN_Handle inPinHandle) {
        pinHandle = inPinHandle;
    
        Task_Params_init(&txTaskParams);
        txTaskParams.stackSize = RFEASYLINKTX_TASK_STACK_SIZE;
        txTaskParams.priority = RFEASYLINKTX_TASK_PRIORITY;
        txTaskParams.stack = &txTaskStack;
        txTaskParams.arg0 = (UInt)1000000;
    
        Task_construct(&txTask, rfEasyLinkTxFnx, &txTaskParams, NULL);
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        Semaphore_Params semParams_1;
        Semaphore_Params semParams_2;
    
        /* Call driver init functions. */
        Board_initGeneral();
    
        PINCC26XX_setWakeup(ButtonTableWakeUp);
    
        /* Open LED pins */
        pinHandle = PIN_open(&pinState, pinTable);
        Assert_isTrue(pinHandle != NULL, NULL);
    
        PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
        PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
    
        /* Configure semaphore 1. */
        Semaphore_Params_init(&semParams_1);
        semParams_1.mode = Semaphore_Mode_BINARY;
        Semaphore_construct(&but1_Sem, 0, &semParams_1);
    
        /* Configure semaphore 1. */
        Semaphore_Params_init(&semParams_2);
        semParams_2.mode = Semaphore_Mode_BINARY;
        Semaphore_construct(&but2_Sem, 0, &semParams_2);
    
        uint32_t rSrc = SysCtrlResetSourceGet();
    
        /* Do pin init before starting BIOS */
        /* If coming from shutdown, use special gpio table.*/
        if(rSrc == RSTSRC_WAKEUP_FROM_SHUTDOWN) {
            uint8_t i = 0;
            uint32_t but0 = 0;
            uint32_t but1 = 0;
            for (i = 0; i < 10; i++)
            {
               but0 = but0 + PINCC26XX_getInputValue(Board_PIN_BUTTON0);
               but1 = but1 + PINCC26XX_getInputValue(Board_PIN_BUTTON1);
               CPUdelay(800*50);
    
            }
            if (but0 < 2) {
                Semaphore_post(Semaphore_handle(&but1_Sem));
                PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
            }
            if (but1 < 2) {
                Semaphore_post(Semaphore_handle(&but2_Sem));
                PIN_setOutputValue(pinHandle, Board_PIN_LED2, 1);
            }
        }
        else
        {
            Power_shutdown(0, 0);
        }
    
        Board_shutDownExtFlash();
    
        txTask_init(pinHandle);
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    
    I have looked some more on it and doing two buttons from shutdown is a bit tricky since the chip starts the code from the first line in main() after waking up from shutdown. The only method I got to work was to sample the IOs as soon as possible in the code. Here I have sampled the input 10 times with a delay in between to check that it's still pressed. 

    The code is not robust since if you press too long the code goes into a state. Some error handling should be added.  

  • Hello TER

    Thank you for the code really. However, it didn't send the packet at all to the receiver. could you just help me out with one button press->send packet-> shutdown mode? Just using one button. I will look into the two button thing later.

    Also i thought yesterday to import the rfEasyLinkTx into the pinSHutdown project and try the application. The part that says "iswakingfromShutdown" can include the packet transmission from easyLink. And i can remove the case of putting the controller to shutdown somehow. But i ran into a lot of errors.

  • Hi TER

    I checked this code again that you said and put a code for an external button that i will be using in my application (not a launchpad button)

    However, the problem is that the code isn't entering the if loop even after the button is pressed and thus it is not transmitting the packet. Power_shutdown API is also not being called. i implemented a delay in my debounce logic however, no luck. doesn't enter the loop

    attaching my segment of your code below.

    if(PIN_getInputValue(EMR_STOP)==0 )
        {
            CPUdelay((uint32_t)((48000000/3)*0.050f));
            EasyLink_transmitAsync(&txPacket, txDoneCb);
    
    
            /* Wait 300ms for Tx to complete */
            if(Semaphore_pend(txDoneSem, (300000 / Clock_tickPeriod)) == FALSE)
            {
                /* TX timed out, abort */
                if(EasyLink_abort() == EasyLink_Status_Success)
                {
                    /*
                     * Abort will cause the txDoneCb to be called and the txDoneSem
                     * to be released, so we must consume the txDoneSem
                     */
                   Semaphore_pend(txDoneSem, BIOS_WAIT_FOREVER);
                }
            }
            /* Go to shutdown */
    
            PIN_setOutputValue(pinHandle, Board_PIN_LED1, 0);
            PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
    
            Power_shutdown(0, 0);
           
        }
    }

    Also the code has to run repeatedly i.e the controller should be in shutdown and wait for the next button click.