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: Using TI-RTOS UART and RF Rx at the same time

Part Number: LAUNCHXL-CC1310

Tool/software: TI-RTOS

I am trying to get UART and RF working together. Specifically, I need to listen for a RF packet, and transmit it over UART whenever a packet is received. I have tried to use the example provided here for the CC1350 as a base, but I do not receive my RF packet if my UartTxTask is initiallized.

Here is my code:

/***** Includes *****/
#include <stdlib.h>
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>

/* Drivers */
#include <ti/drivers/rf/RF.h>
#include <ti/drivers/PIN.h>
#include <ti/drivers/UART.h>
#include <ti/sysbios/knl/Mailbox.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>

#include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)

/* Board Header files */
#include "Board.h"

#include "RFQueue.h"
#include "smartrf_settings/smartrf_settings.h"

#include <stdlib.h>

/* Pin driver handle */
static PIN_Handle ledPinHandle;
static PIN_State ledPinState;

/*
 * Application LED pin configuration table:
 *   - All LEDs board LEDs are off.
 */
PIN_Config pinTable[] =
{
    Board_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
};

enum rf_mode  {
    RX_MODE,
    TX_MODE,
};

volatile enum rf_mode mode = RX_MODE;

/* Packet RX Configuration */
#define DATA_ENTRY_HEADER_SIZE 8  /* Constant header size of a Generic Data Entry */
#define MAX_LENGTH             2 /* 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) */

/***** Defines *****/
#define RX_TASK_STACK_SIZE 1024
#define RX_TASK_PRIORITY   1

#define UART_TX_TASK_STACK_SIZE 1024
#define UART_TX_TASK_PRIORITY   2

/***** Prototypes *****/
static void rxTaskFunction(UArg arg0, UArg arg1);
static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
static void uartTxTaskFunction(UArg arg0, UArg arg1);

/***** Variable declarations *****/
static Task_Params rxTaskParams;
Task_Struct rxTask;    /* not static so you can see in ROV */
static uint8_t rxTaskStack[RX_TASK_STACK_SIZE];

static Task_Params uartTxTaskParams;
Task_Struct uartTxTask;    /* not static so you can see in ROV */
static uint8_t uartTxTaskStack[UART_TX_TASK_STACK_SIZE];

Semaphore_Struct semRxStruct;
Semaphore_Handle semRxHandle;

Semaphore_Struct semUartTxStruct;
Semaphore_Handle semUartTxHandle;

static RF_Object rfObject;
static RF_Handle rfHandle;
static RF_CmdHandle rfRxCmd;

UART_Handle uart = NULL;
UART_Params uartParams;

/* 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;
uint8_t packetReady = 0;
static uint8_t packetLength;
static uint8_t* packetDataPointer;
//uint32_t time;

static PIN_Handle pinHandle;

static uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */


/***** Function definitions *****/
void RxTask_init(PIN_Handle ledPinHandle) {
    pinHandle = ledPinHandle;

    Task_Params_init(&rxTaskParams);
    rxTaskParams.stackSize = RX_TASK_STACK_SIZE;
    rxTaskParams.priority = RX_TASK_PRIORITY;
    rxTaskParams.stack = &rxTaskStack;
    rxTaskParams.arg0 = (UInt)1000000;

    Task_construct(&rxTask, rxTaskFunction, &rxTaskParams, NULL);
}

void UartTxTask_init(PIN_Handle ledPinHandle) {
    pinHandle = ledPinHandle;

    Task_Params_init(&uartTxTaskParams);
    uartTxTaskParams.stackSize = UART_TX_TASK_STACK_SIZE;
    uartTxTaskParams.priority = UART_TX_TASK_PRIORITY;
    uartTxTaskParams.stack = &uartTxTaskStack;
    uartTxTaskParams.arg0 = (UInt)1000000;

    Task_construct(&uartTxTask, uartTxTaskFunction, &uartTxTaskParams, NULL);
}
static void rxTaskFunction(UArg arg0, UArg arg1)
{
    RF_Params rfParams;
    RF_Params_init(&rfParams);

    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 */
    RF_cmdPropRx.pQueue = &dataQueue;           /* Set the Data Entity queue for received data */
    RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;  /* Discard ignored packets from Rx queue */
    RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;   /* Discard packets with CRC error from Rx queue */
    RF_cmdPropRx.maxPktLen = MAX_LENGTH;        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
    RF_cmdPropRx.pktConf.bRepeatOk = 1;
    RF_cmdPropRx.pktConf.bRepeatNok = 1;

   if(!rfHandle)
       {
            /* Request access to the radio */
            rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);

            /* 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_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, IRQ_RX_ENTRY_DONE);
        Semaphore_pend(semRxHandle, BIOS_WAIT_FOREVER);
    }

}

void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
    if (e & RF_EventRxEntryDone)
    {
        /* Toggle pin to indicate RX */
        PIN_setOutputValue(pinHandle, 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));

        packetReady = 1;

        RFQueue_nextEntry();

        Semaphore_post(semUartTxHandle);
    }
}

#define UART_TX_BUFFER_SIZE 256
char uartTxBuffer[UART_TX_BUFFER_SIZE];

static void uartTxTaskFunction(UArg arg0, UArg arg1)
{
    int readShift;
    uint8_t input[packetLength];
    for(readShift = 0; readShift < 2; readShift++)
                    {
                        input[readShift] = packet[readShift];
                    }
    /* Open UART if not already open */
    if (uart == NULL) {
        /* 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 = 9600;
        uart = UART_open(Board_UART0, &uartParams);

        if (uart == NULL) {
            System_abort("Error opening the UART");
        }
    }

    while (1)
    {
        Semaphore_pend(semUartTxHandle, BIOS_WAIT_FOREVER);
        UART_write(uart, input, 3);

        /* Cancel Rx */
    //    RF_cancelCmd(rfHandle, rfRxCmd, 0);
        Semaphore_post(semRxHandle);

    }



}

/*
 *  ======== main ========
 */
int main(void)
{
    Semaphore_Params semParams;

    /* Call driver init functions. */
    Board_initGeneral();

    /* Open LED pins */
    ledPinHandle = PIN_open(&ledPinState, pinTable);
    if(!ledPinHandle)
    {
        System_abort("Error initializing board LED pins\n");
    }

       /* Construct a Semaphore object to be used as a resource lock, inital count 0 */
       Semaphore_Params_init(&semParams);
       Semaphore_construct(&semRxStruct, 0, &semParams);

       /* Obtain instance handle */
       semUartTxHandle = Semaphore_handle(&semUartTxStruct);

       /* Construct a Semaphore object to be used as a resource lock, inital count 0 */
       //Semaphore_Params_init(&semParams);
       Semaphore_construct(&semUartTxStruct, 0, &semParams);


    /* Initialize task */
    RxTask_init(ledPinHandle);

    UartTxTask_init(ledPinHandle);

    /* Start BIOS */
    BIOS_start();

    return (0);
}

If I comment out my UartTxTask_init in my main (line 294) RF Rx works again. Any ideas as to why I can only seem to run one task at a time? I'm pretty sure I've got my Semaphores set up properly, so I don't think it's that.

  • Hello Ryan, 

    Looks like your goal is to Receive a packet and send the received data to UART. In this case you need to use the uartRxTask and not uartTxTask from the base example you referred to. uartTxTask will read the data from the UART and when it sees end of line, it will transmit this data. uartRxTask will send the Rx data to uart. Please use uartRxTask instead of uartTxTask. 

    Regards,

    Prashanth