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/CC1310: UART_write() function does not operate propely.

Part Number: CC1310
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

Hello,

I'm beginner of TI product and CCS.

Recently, I bought CC1310 EVK and make some program using example codes but there are several issues.

1. UART_write() fucntion

- When I try to use UART_write() function continously, it doesn't work well

Eg)

const char prompt1[] = "prompt1 \n";

const char prompt2[] = "prompt2 \n";

const char prompt3[] = "prompt3 \n";

- using echo example and modify

//UART_read(uart, &input, 1);

//UART_write(uart, &input, 1);

UART_write(uart, prompt1, sizeof[prompt1]);

UART_write(uart, prompt2, sizeof[prompt2]);

UART_write(uart, prompt3, sizeof[prompt3]);

when I use this function, always system stopped at 2nd UART_write() function colled.

I don't know why this happles. Do I need some time interval before function call?

2. RF echo

using sample code (sample code also based on RXpacket example, TXpacket example),

(sample code link : https://e2e.ti.com/support/wireless_connectivity/proprietary_sub_1_ghz_simpliciti/f/156/t/505250 )

and modify to rf echo program, system dies around 570~585th trying.

modified operation is simple

- create 80bytes packet and send (mudule 1)

- re send received packet(module 2 - module1 - module2 - module1 - ....infinite echo)

that system stopped around 570~585th operation. I've suspect memory problem, so I reduced the packet size to 20bytes and test again.

but same problem occurs..(packet interval is 500ms)

3. output files

From CCS7, output file created "project name.out" in Debug folder.

but output file is too big to use. (around 2MB)

- Is it automatically converted to bin file when I write to the flash using flash programmer2?

- if not, can I make ***.bin file using CCS7?

I would appreciate if you could inform me suspected problems about these kind of issues so I could test.

Thank you very much. Have a merry chrismas.

  • Hi,

    Kim Yoon Whoi said:
    When I try to use UART_write() function continously, it doesn't work well

    Can you tell us a little bit more what happens? Did you stop the debugger to see if the program is stuck a specific line of code? What about the ROV view (under the tools menu)? Any errors or task stack overflows?

    Kim Yoon Whoi said:
    I've suspect memory problem, so I reduced the packet size to 20bytes and test again.

    I believe that you are right about the memory problem, but it sounds more like memory that is not freed after it is being used. In some cases, depending on the memory configuration, the memory is "freed" but cannot be reallocated.

    Kim Yoon Whoi said:
    Is it automatically converted to bin file when I write to the flash using flash programmer2?

    The .out is used for debugging (with symbols and additional debugger information). If you don't have a .bin file, you have to change the project properties and add a post-build step in the linker. I don't know the exact command, but I found a thread in the CCS forum that might get you started. You can look on the forums for generating .bin in CCS.

    Regards,

    Michel

  • Dear Michel

    Thank you for your kindness.

    1. UART problem
    - From the debug screen, buffer address to be written seems 'null' when 2nd or 3rd UART_write() called.
    I don't know why..I give them right address. (const char[] 's name is address...right?)
    - program is stuck a specific line of code. arrow for line suddenly disappear.
    [dissapear point]
    -UARTCC26XX.c
    int UARTCC26XX_write(UART_Handle handle, const void *buffer, size_t size)
    /* If writeMode is blocking, block and get the status. */
    if (object->writeMode == UART_MODE_BLOCKING) {
    /* Pend on semaphore and wait for Hwi to finish. */
    [LINE 1028] if (!Semaphore_pend(Semaphore_handle(&(object->writeSem)), object->writeTimeout)) {
    line arrow dissapears..
    at this point, handle, buffer, size's address is missing. (type : unknown, value : identifier not found:ahandle, buffer, size, Address : blank)


    2. RF echo stop problem
    - In my opinion, it seems not memory problem.
    If it was memory problem, then overflow point should be changed.
    But when I changed packet size to 1/3 for test, same problem happens. (it also happens at 570~590th try)
    - FYI, I didn't allocate memory in application. (no malloc function used. all variables should be in stack, not heap.)
    - So, if it is memory problem, then RF driver may occurs problem. (I didn't change RF settings..cause I don't know how to modify)

    [FYI]
    -Master module operation
    1. Packet received from slave module.
    2. Increase seq number. (all data excep 'sequence feild' is same with received packet)
    3. Send packet to slave module (packet interval is 1.0 seconds)

    - Slave module operation
    1. Packet received from master module.
    2. Send packet to master module.(packet interval is 0.5 seconds)
    (all data is same as received packet)

    - I've changed 'master module's packet interval to 0.5 seconds (same as slave module's)
    problem seems better. (I'll test this all night and check it tomorrow)

    Anyway, master module and slave module does not send packet at the same time.
    (because each module send packet after they received packet which means other module already send packet and stayed in RX mode)
    so, if the problem was packet interval should not affect this problem.(in my opinion)...but packet interval affect this problem actually..
    It confusing me..


    BTW, I would appreciate if you inform me the URL address or file name of "RF setting manual". (Eg. How to modify RF parameters, ..)

    3. bin file make problem
    - I don't understand what you suggested to me. I would appreciate if you could inform me the URL address (what you found in forums?)

    *More question.
    Is it possible using different preamble in CC1310?
    eg, when module1 send packet(TXmode), use 8bytes preamble, when module1 receive packet(RXmode) using 4bytes preamble.
    - every module should have both TX and RX mode. (request <-> response)

    I've found [RF_cmdPropRadioDivSetup.preamConf.nPreamBytes ] from "smartrf_setting.c"
    could I modify this value in run time?
    (eg. RF_cmdPropRadioDivSetup..preamConf.nPreamBytes = 0x08;

    or each time when this feild modified, RF_Close() and RF_Open() again?
    if then, is ther any possibilties that miss packet while mode changing?
  • Hi,

    Kim Yoon Whoi said:
    1. UART problem

    Can you show us more code (where your task is initialized. where your UART is initialized and open)? Please click on Use Rich Formatting (bottom right of the box) and select the Syntax Highlighter to insert your code.

    If you put a breakpoint on the second UART_write and follow the code step by step, do you see an address for prompt2 (before you enter UART_write)?

    Are you using Callback mode or Blocking? You should not send another message before the first one is finished "writing" in callback mode.

    Kim Yoon Whoi said:
    2. RF echo stop problem

    I might be wrong in this case, but the most common reason for problems is memory problem (the allocate would be done by the RF driver).

    When the program stops working, have you stopped the debugger to see if it stuck on a specific line?

    Have you checked the ROV for errors?

    Kim Yoon Whoi said:
    3. bin file make problem

    I suggest that you read this Wiki. You will have to add a Post build step to generate your bin file. This wiki page contains the information that you need.

    Kim Yoon Whoi said:
    3. bin file make problem

    I don't know much about RF so I will not able to answer those additional questions. I suggest that you post those in the Sub-1 Ghz forum.

    Regards,

    Michel

  • 1. UART problem

    I'll post similar code as belows.

    ============================================= below=============================================

    /*
     * Copyright (c) 2015, 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.
     */

    /***** 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 <driverlib/rf_prop_mailbox.h>
    #include <ti/drivers/UART.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_LED4 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        Board_LED3 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };

    #define UART 1

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

    /* TX Configuration */
    #define DATA_ENTRY_HEADER_SIZE 8  /* Constant header size of a Generic Data Entry */
    #define MAX_LENGTH             90//30 /* 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 TX_TASK_STACK_SIZE 1024
    #define TX_TASK_PRIORITY   3

    /* TX Configuration */
    #define PAYLOAD_LENGTH      90//30
    #define PACKET_INTERVAL     (uint32_t)(4000000*0.5f) /* Set packet interval to 500ms */

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

    /***** 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 txTaskParams;
    Task_Struct txTask;    /* not static so you can see in ROV */
    static uint8_t txTaskStack[TX_TASK_STACK_SIZE];

    Semaphore_Struct semTxStruct;
    Semaphore_Handle semTxHandle;

    Semaphore_Struct semRxStruct;
    Semaphore_Handle semRxHandle;


    static RF_Object rfObject;
    static RF_Handle rfHandle;


    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    #endif
    static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                                     MAX_LENGTH,
                                                                     NUM_APPENDED_BYTES)];

    /* 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;
    uint32_t time;
    static uint8_t txPacket[PAYLOAD_LENGTH];
    static uint16_t seqNumber;

    static PIN_Handle pinHandle;

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

    #if UART
    static UART_Handle uart;
    static UART_Params uartParams;
    const char RX_Prompt[] = "[RX]\n";
    const char TX_Prompt[] = "[TX]\n";
    void initUART()
    {
        Board_initUART();

        /* 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");
        }
    }
    #endif

    /***** 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);
    }

    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 = 0;
        RF_cmdPropRx.pktConf.bRepeatNok = 0;

        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_LED3,!PIN_getOutputValue(Board_LED3));

            /* 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));
    #if UART
            UART_write(uart, RX_Prompt, sizeof(RX_Prompt));
            UART_write(uart, packet, packetLength);
    #endif

            Semaphore_post(semTxHandle);

            RFQueue_nextEntry();
        }
    }

    #if 1
    /***** 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)
    {
        uint32_t time;
        RF_Params rfParams;
        RF_Params_init(&rfParams);

        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        RF_cmdPropTx.pPkt = txPacket;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_ABSTIME;
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.startTime = 0;

        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);
        }

        /* Get current time */
        time = RF_getCurrentTime();
        while(1)
        {
            Semaphore_pend(semTxHandle, BIOS_WAIT_FOREVER);

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

            /* Set absolute TX time to utilize automatic power management */
            time += PACKET_INTERVAL;
            RF_cmdPropTx.startTime = time;

            /* Send packet */
            RF_EventMask result = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);
            if (!(result & RF_EventLastCmdDone))
            {
                /* Error */
                while(1);
            }
    #if UART
            UART_write(uart, TX_Prompt, sizeof(TX_Prompt));
    #endif
            PIN_setOutputValue(pinHandle, Board_LED4,!PIN_getOutputValue(Board_LED4));
            Semaphore_post(semRxHandle);

        }
    }
    #endif

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

        /* Call board init functions. */
        Board_initGeneral();
    #if UART
        initUART();
    #endif
        /* 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(&semTxStruct, 0, &semParams);
        Semaphore_construct(&semRxStruct, 0, &semParams);


        /* Obtain instance handle */
        semTxHandle = Semaphore_handle(&semTxStruct);
        semRxHandle = Semaphore_handle(&semRxStruct);

        /* Initialize task */
        RxTask_init(ledPinHandle);

        /* Initialize task */
        TxTask_init(ledPinHandle);

        /* Start BIOS */
        BIOS_start();

        return (0);
    }

    ===============================================================================================

    2. I can't check ROV because the problem occurs around 585th try. I can't try manually.

    BTW, packet interval affect this problem.

    3. Thank you for you suggestion.

    I'll ask RF forum for RF settings.

  • Hi,

    1. UART problem
    - I would like to attach simple code as below.
    (it is RF echo example which was given from TI forum, and I add uart code for test)

    2. RF echo problem.
    - I also suspect memory problem before, but after I modified "PACKET_INTERVAL" to 500ms, problem dissapeared.
    I still worried about this issue because I don't know why problem occurs previously.
    FYI,
    before modify : master module's interval was 1.0 seconds, slave module's interval was 0.5 seconds.
    (each module send packet after they received packet. so two module does not send packets at the same time)

    3. RF setting change while running issue
    - I would ask this issue to RF forum as your suggestion.

    Thank you very much.

    ============================= below =========================
    /***** 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 <driverlib/rf_prop_mailbox.h>
    #include <ti/drivers/UART.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_LED4 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    Board_LED3 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    PIN_TERMINATE
    };

    #define UART 1

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

    /* TX Configuration */
    #define DATA_ENTRY_HEADER_SIZE 8 /* Constant header size of a Generic Data Entry */
    #define MAX_LENGTH 90//30 /* 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 TX_TASK_STACK_SIZE 1024
    #define TX_TASK_PRIORITY 3

    /* TX Configuration */
    #define PAYLOAD_LENGTH 90//30
    #define PACKET_INTERVAL (uint32_t)(4000000*0.5f) /* Set packet interval to 500ms */

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

    /***** 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 txTaskParams;
    Task_Struct txTask; /* not static so you can see in ROV */
    static uint8_t txTaskStack[TX_TASK_STACK_SIZE];

    Semaphore_Struct semTxStruct;
    Semaphore_Handle semTxHandle;

    Semaphore_Struct semRxStruct;
    Semaphore_Handle semRxHandle;


    static RF_Object rfObject;
    static RF_Handle rfHandle;


    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    #endif
    static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
    MAX_LENGTH,
    NUM_APPENDED_BYTES)];

    /* 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;
    uint32_t time;
    static uint8_t txPacket[PAYLOAD_LENGTH];
    static uint16_t seqNumber;

    static PIN_Handle pinHandle;

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

    #if UART
    static UART_Handle uart;
    static UART_Params uartParams;
    const char RX_Prompt[] = "[RX]\n";
    const char TX_Prompt[] = "[TX]\n";
    void initUART()
    {
    Board_initUART();

    /* 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");
    }
    }
    #endif

    /***** 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);
    }

    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 = 0;
    RF_cmdPropRx.pktConf.bRepeatNok = 0;

    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_LED3,!PIN_getOutputValue(Board_LED3));

    /* 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));
    #if UART
    UART_write(uart, RX_Prompt, sizeof(RX_Prompt));
    UART_write(uart, packet, packetLength);
    #endif

    Semaphore_post(semTxHandle);

    RFQueue_nextEntry();
    }
    }

    #if 1
    /***** 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)
    {
    uint32_t time;
    RF_Params rfParams;
    RF_Params_init(&rfParams);

    RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
    RF_cmdPropTx.pPkt = txPacket;
    RF_cmdPropTx.startTrigger.triggerType = TRIG_ABSTIME;
    RF_cmdPropTx.startTrigger.pastTrig = 1;
    RF_cmdPropTx.startTime = 0;

    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);
    }

    /* Get current time */
    time = RF_getCurrentTime();
    while(1)
    {
    Semaphore_pend(semTxHandle, BIOS_WAIT_FOREVER);

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

    /* Set absolute TX time to utilize automatic power management */
    time += PACKET_INTERVAL;
    RF_cmdPropTx.startTime = time;

    /* Send packet */
    RF_EventMask result = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);
    if (!(result & RF_EventLastCmdDone))
    {
    /* Error */
    while(1);
    }
    #if UART
    UART_write(uart, TX_Prompt, sizeof(TX_Prompt));
    #endif
    PIN_setOutputValue(pinHandle, Board_LED4,!PIN_getOutputValue(Board_LED4));
    Semaphore_post(semRxHandle);

    }
    }
    #endif

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

    /* Call board init functions. */
    Board_initGeneral();
    #if UART
    initUART();
    #endif
    /* 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(&semTxStruct, 0, &semParams);
    Semaphore_construct(&semRxStruct, 0, &semParams);


    /* Obtain instance handle */
    semTxHandle = Semaphore_handle(&semTxStruct);
    semRxHandle = Semaphore_handle(&semRxStruct);

    /* Initialize task */
    RxTask_init(ledPinHandle);

    /* Initialize task */
    TxTask_init(ledPinHandle);

    /* Start BIOS */
    BIOS_start();

    return (0);
    }
    ============================================================end
  • Hi,

    Kim Yoon Whoi said:
    (it is RF echo example which was given from TI forum, and I add uart code for test)

    I don't see in your code where you added the UART_write. Instead of pasting the code, PLEASE CLICK ON USE RICH FORMATTING and INSERT CODE WITH SYNTAX HIGHLIGHTER. The code is very hard to read in plain text. You can also attach the file instead of pasting the code.

    Kim Yoon Whoi said:
    2. RF echo problem.

    I am not sure about this, but it seems like you wait PACKET_INTERVAL before you read again. If your intervals are not the same, you will send more messages than you read, you will accumulate messages until the queue gets full. (you get blocked because you use Semaphores to synchronize your send and receive)

    My guess is that your final code should not use packet intervals to avoid this problem. But I don't know how to change the code to do that.

    Regards,

    Michel

  • 1351.rfPacketRx.c

    Hi,

    1.  I've attached source code. This code is based on forum example (https://e2e.ti.com/support/wireless_connectivity/proprietary_sub_1_ghz_simpliciti/f/156/t/505250)

    UART_write() is called from callback(), before "Semaphore_post(semTxHandle)" as below

    ==========below=======

    #if UART
            UART_write(uart, RX_Prompt, sizeof(RX_Prompt));
            UART_write(uart, packet, packetLength);
    #endif

            Semaphore_post(semTxHandle);

    =====================

    and also called from txTaskFunction(), before led control as below

    =========below=========

    #if UART
            UART_write(uart, TX_Prompt, sizeof(TX_Prompt));
    #endif
            PIN_setOutputValue(pinHandle, Board_LED4,!PIN_getOutputValue(Board_LED4));

    ======================

    2. PACKET_INTERVAL is used for tx.

    This program migth wait interval time before change to rx mode,

    but the module will not send packet when other module is in tx mode becaue it only send packet when it received packet first

    (which means other module already send packet and changed to rx mode.)

     /* Get current time */
        time = RF_getCurrentTime();
        while(1)
        {
            ....
            }

            /* Set absolute TX time to utilize automatic power management */
            time += PACKET_INTERVAL;
            RF_cmdPropTx.startTime = time;

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

    Thank you very much.

  • Hi.

    Kim Yoon Whoi said:
    #if UART
            UART_write(uart, RX_Prompt, sizeof(RX_Prompt));
            UART_write(uart, packet, packetLength);
    #endif

    Your original post said that UART_write(uart, promptxx, sizeof(promptxx) didn't work. This is slightly different.

    There are a few things to check before we continue any further.

    1. If you start an empty project (no radio), can you use multiple UART_write?
    2. I don't know who calls the callback, but it is very possible that the long processing of the UART_write (especially in BLOCKING mode inside a callback) might cause problems in the radio task. Try moving it outside of the callback.

    Kim Yoon Whoi said:
    2. PACKET_INTERVAL is used for tx.

    Unfortunately, I don't know enough about RF to be able to understand what the PACKET_INTERVAL does. In my mind, I thought it meant that the Tx would send repeatedly at the given interval. So if your interval was 500ms in one device and 1000ms in the other device, then one device would send two messages while the other only sent one message. That would mean that one of the queues would eventually overflow since you only read once.

    For that question, I will have to say that I don't know the answer and it might be better answered in the same forum where you found the source code.

    Regards,

    Michel