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: Blink led with RFexample and UART

Other Parts Discussed in Thread: CC1310

Tool/software: TI-RTOS

I'm working with my CC1310 devices and some examples found on the main resources. I'm focusing on RF communication between two devices, through the exchange of strings through the serial port. For example I write "HELLO" from COM 1 and get "HELLO" from COM 2. Now for this example, I would like to insert a game with LEDs. For example, if I send a red led to access and if it receives a green LED on. I have already done this step and it works. Now, I would like to do that if I send the string and the receiver is disconnected, the red LED should flash for 1 second. How can I do? I saw the RFEcho examples, I tried to implement but the LED is always on. Any suggestions from you?

  • You should implement an application acknowledgment on receiver side which means, sender sends a messages to receiver and receiver needs to respond with an acknowledgment to sender. In the way, if sender doesn't get this acknowledgment for a while after sending a message, you can let red LED flash for 1 second.

  • Does the example of RFEchoTX and RX not already do this? I tried to implement that, but without success

  • As I know, rfEasyLinkEchoTX and RX already implement ack mechanism. I couldn't understand what you mean you try to implement that without success. I suggest you to read first.

  • There is no need to complicate this by using EasyLink. You are correct that the RFEchoTX example waits for an Ack.

    However, you need to give us more information other than you did not succeed, if we shall be able to help you.

    What have you done in your code and what does not work (obviously you are not running the RFEchoTX without modifications).

    When we know what you are doing in your code, we also need to know where it fails. Are you not able to receive the message on the COM port, is the TX failing, or is TX OK but you do not receive the ACK?

    BR

    Siri

  • Hi Siri, I see how is implement the ack with RFEcho example and I have modify the my code with some information of RFEcho Example. The my problem is that the led red is only turn on, even when the receivetor is open. This is my code: 

    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/Assert.h>
    #include <ti/drivers/UART.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include "RFQueue.h"
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    static void echoCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    /* Board Header files */
    #include "Board.h"
    
    /* Application Header files */
    #include "smartrf_settings/smartrf_settings.h"
    
    /***** Defines *****/
    #define TX_TASK_STACK_SIZE 1024
    #define TX_TASK_PRIORITY   2
    
    /* Packet TX Configuration */
    #define PAYLOAD_LENGTH      30
    #define PACKET_INTERVAL     (uint32_t)(4000000*0.5f) /* Set packet interval to 500ms */
    #define NUM_APPENDED_BYTES  2
    
    /* Do power measurement */
    //#define POWER_MEASUREMENT
    
    /***** Prototypes *****/
    static void txTaskFunction(UArg arg0, UArg arg1);
    
    /***** Variable declarations *****/
    static Task_Params txTaskParams;
    Task_Struct txTask;    /* not static so you can see in ROV */
    static uint8_t txTaskStack[TX_TASK_STACK_SIZE];
    
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    static uint8_t packet[PAYLOAD_LENGTH];
    static uint8_t rxPacket[PAYLOAD_LENGTH + NUM_APPENDED_BYTES - 1];
    static PIN_Handle pinHandle;
    static volatile bool bRxSuccess = false;
    static rfc_dataEntryGeneral_t* currentDataEntry;
    static uint8_t packetLength;
    static uint8_t* packetDataPointer;
    
    /*
     * 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,
    #if defined __CC1352R1_LAUNCHXL_BOARD_H__
        Board_DIO30_RFSW | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #endif
    #ifdef POWER_MEASUREMENT
    #if !defined(__CC1352R1_LAUNCHXL_BOARD_H__) && !defined(__CC26X2R1_LAUNCHXL_BOARD_H__)
        CC1350_LAUNCHXL_DIO30_SWPWR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #endif
    #endif
        PIN_TERMINATE
    };
    
    /***** Function definitions *****/
    void TxTask_init(PIN_Handle inPinHandle)
    {
        pinHandle = inPinHandle;
    
        Task_Params_init(&txTaskParams);
        txTaskParams.stackSize = TX_TASK_STACK_SIZE;
        txTaskParams.priority = TX_TASK_PRIORITY;
        txTaskParams.stack = &txTaskStack;
        txTaskParams.arg0 = (UInt)1000000;
    
        Task_construct(&txTask, txTaskFunction, &txTaskParams, NULL);
    }
    
    static void txTaskFunction(UArg arg0, UArg arg1)
    {
    #ifdef POWER_MEASUREMENT
        /* Shutdown external flash */
        Board_shutDownExtFlash();
    #if !defined(__CC1352R1_LAUNCHXL_BOARD_H__) && !defined(__CC26X2R1_LAUNCHXL_BOARD_H__)
        /* Route out PA active pin to Board_DIO30_SWPWR */
        PINCC26XX_setMux(ledPinHandle, Board_DIO30_SWPWR, PINCC26XX_MUX_RFC_GPO1);
    #endif
    #endif
    
        /* Init UART */
        char        input;
        const char  startPrompt[] = "Start typing\r\n";
        UART_Handle uart;
        UART_Params uartParams;
    
        UART_init();
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uart = UART_open(Board_UART0, &uartParams);
    
        if (uart == NULL) {
             /* UART_open() failed */
             while (1);
        }
    
        /* Write to the UART before starting RX */
        UART_write(uart, startPrompt, sizeof(startPrompt));
    
        /* Init RF */
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        RF_cmdPropTx.pPkt = packet;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
    
        /* Request access to the radio */
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
     /*   if(rfHandle == NULL){
            PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
        }*/
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        /* Get current time */
        while(1)
        {
            uint8_t i = 0;
            do
            {
               UART_read(uart, &input, 1);
               UART_write(uart, &input, 1);
               packet[i++] = input;
            }
            while (input != '\r');
    
            /*skip CR */
            RF_cmdPropTx.pktLen = i-1;
    
            /* Send packet */
            RF_EventMask terminationReason =
                            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal,
                                      echoCallback, (RF_EventCmdDone | RF_EventRxEntryDone |
                                      RF_EventLastCmdDone));
    
    //#ifndef POWER_MEASUREMENT
    //        PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
    //#endif
        }
    }
    static void echoCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
    #ifdef LOG_RADIO_EVENTS
        eventLog[evIndex++ & 0x1F] = e;
    #endif// LOG_RADIO_EVENTS
    
        if((e & RF_EventCmdDone) && !(e & RF_EventLastCmdDone))
        {
            /* Successful TX */
            /* Toggle LED1, clear LED2 to indicate TX */
            PIN_setOutputValue(pinHandle, Board_PIN_LED1,
                               !PIN_getOutputValue(Board_PIN_LED1));
            PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
        }
        else if(e & RF_EventRxEntryDone)
        {
            /* Successful RX */
            bRxSuccess = true;
    
            /* 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 + status byte to the rxPacket variable */
            memcpy(rxPacket, packetDataPointer, (packetLength + 1));
    
            /* Check the packet against what was transmitted */
            int16_t status = memcmp(packet, rxPacket, packetLength);
    
            if(status == 0)
            {
                /* Toggle LED1, clear LED2 to indicate RX */
                PIN_setOutputValue(pinHandle, Board_PIN_LED1,
                                   !PIN_getOutputValue(Board_PIN_LED1));
                PIN_setOutputValue(pinHandle, Board_PIN_LED2, 0);
            }
            else
            {
                /* Error Condition: set both LEDs */
                PIN_setOutputValue(pinHandle, Board_PIN_LED1, 1);
                PIN_setOutputValue(pinHandle, Board_PIN_LED2, 1);
            }
    
            RFQueue_nextEntry();
        }
        else if((e & RF_EventLastCmdDone) && !(e & RF_EventRxEntryDone))
        {
            if(bRxSuccess == true)
            {
                /* Received packet successfully but RX command didn't complete at
                 * the same time RX_ENTRY_DONE event was raised. Reset the flag
                 */
                bRxSuccess = false;
            }
            else
            {
                /* RX timed out */
                /* Set LED2, clear LED1 to indicate TX */
                PIN_setOutputValue(ledPinHandle, Board_PIN_LED1, 0);
                PIN_setOutputValue(ledPinHandle, Board_PIN_LED2, 1);
            }
        }
        else
        {
            /* Error Condition: set both LEDs */
            PIN_setOutputValue(ledPinHandle, Board_PIN_LED1, 1);
            PIN_setOutputValue(ledPinHandle, Board_PIN_LED2, 1);
        }
    }
    
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call driver init functions. */
        Board_initGeneral();
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        Assert_isTrue(ledPinHandle != NULL, NULL);
    
        /* Initialize task */
        TxTask_init(ledPinHandle);
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }

  • In the code above, you are never sending any RX command, so there is no way you can receive any packets.

    To enter RX mode, you need to send a RF_cmdPropRx command. You also needs to set up the queue where you want to store the receive packet.

    In the RFEchoTX example, the RX command is chained to the TX command.

    Siri

  • The Line 169 send the packet, it wrong?

  • Do you set a breakpoint on line 170 to make sure it hits to send packet?

  • If I use the program without implementing lines 180 through 256, it works and sends the message. What I would like is that if it sends the message and the receiver is not there, it lights up a LED.

  • What you want (I think) is to know if the receiver received the packet or not. For the transmitter to know that, it must enter RX state after it has transmitted to see if the receiver sendt an ACK. This is what is done in the echo example. In the echo example, the TX command is chained to the RX command so that the radio enters RX after TX to listen for the ACK. In your code, you never send an RX command, the radios does not enter RX, and you can not know if the receiver received the packet or not.

  • How Can I do this? Can you help me?

  • The code is already implemented in the RFEcho example, and unfortunately we do not have the resources to write you a demo code.

    If you do not want to use command chaing, you can send an RX command after the TX command has returned, and then make this time out after a given time (using end triggeres). If the RX command return without having received a n ACK packet, you can assume that your receiver is off.

    BR

    Siri