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.

LAUNCHXL-CC1310: TMS320F28379D problem

Part Number: LAUNCHXL-CC1310
Other Parts Discussed in Thread: TMS320F28379D, CC1310, CC1350

Hi team

Good day!

customer request:

I'm trying to get a TMS320F28379D board to communicate over SPI to a CC1310 launchpad, I then want the CC1310 to broadcast the values that are received over RF, at the moment I can get the CC1310 to receive and interpret the F28379D's values over SPI, but the example code I am using is struggling to receive these values over SPI and transmit over RF.

Regards

Aosker

  • Hi,

    To transmit the information over the air I would recommend you take one of the RF driver examples as a starting point. E.g. RF Packet Tx:

     

  • Sorry I think I missed a bit of explanation here, also apolpogies for the late reply!

    On the CC1310 Launchpad board, I currently am using the rfpacketTx example to transmit packets over RF and the SPISlave example to receive data over SPI from my TMS320F28379D board.

    What I need to happen is for the CC1310 to transmit over RF, the values that are received over SPI.

    I've tried meshing both the examples together and running threads, but these don't seem to work very well.

  • there is no need to do thing very complicated.

    In the rfPacketTX example you can do something like this:

    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        if (ledPinHandle == NULL)
        {
            while(1);
        }
    
        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        RF_cmdPropTx.pPkt = packet;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
    
        // Init SPI
        // Set the SPI up for Slave mode 
        // and SPI_MODE_BLOCKING. 
        handle = SPI_open(Board_SPI, &params);
    
        /* 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)
        {
            // Read the bytes you want to read over SPI
            SPI_transfer(handle, &transaction);
    
            // Copy the rxBuf to packet
    
            /* Send packet */
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);
    
        }
    }

    Siri

  • Oh this looks great, but I have a bunch more questions now if you don't mind.

    A few of the other examples all seem to copy the data to be sent, in very........................interesting ways.

    How might I do it here, going from TMS320F2379D data received over SPI, to CC1310 data to be emitted over RF?

    Thanks

  • You can just set your RF packet to be your SPI buffer:

    spiTransaction.rxBuf = spiRxBuffer;
    
    RF_cmdPropTx.pPkt = spiRxBuffer;
    

    of you can copy the buffer from spiRxBuffer to packet (if RF_cmdPropTx.pPkt = packet):

    memcpy(packet, spiRxBuffer, PAYLOAD_LENGTH)
    

    Siri

  • Hi Siri,

    Thanks so much for this.

    I do still have issues however.

    After following your instructions, I got a fresh copy of the rfPacketTx code and pasted your version of the code from earlier.

    Further to that, in the copy section, I added what you had suggested.

    Having done this, I don't read any data coming in on the SPI lines because the program gets stuck when told to perform SPITransfer.

    Just as a sanity check, I tried to run SPISalve seperately to see if the board can still receive normally, and it does.

    Below is the rfPacketTx code I have been trying to get to read SPI at the same time:

    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    #include <unistd.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    #include <ti/drivers/SPI.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "Board.h"
    #include "smartrf_settings/smartrf_settings.h"
    
    /***** Defines *****/
    
    /* Do power measurement */
    //#define POWER_MEASUREMENT
    /* Packet TX Configuration */
    #define PAYLOAD_LENGTH      30
    #ifdef POWER_MEASUREMENT
    #define PACKET_INTERVAL     5  /* For power measurement set packet interval to 5s */
    #else
    #define PACKET_INTERVAL     500000  /* Set packet interval to 500000us or 500ms */
    #endif
    
    #define SPI_MSG_LENGTH  (40)
    #define SLAVE_MSG       ("123456 ")
    /***** Prototypes *****/
    
    /***** Variable declarations *****/
    
    int potatotrack = 0;
    
    SPI_Handle slaveSpi;
    SPI_Params spiParams;
    SPI_Transaction transaction;
    uint32_t i;
    bool transferOK;
    int32_t status;
    unsigned char slaveRxBuffer[SPI_MSG_LENGTH];
    unsigned char slaveTxBuffer[SPI_MSG_LENGTH];
    
    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 uint16_t seqNumber;
    
    /*
     * 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,
    #ifdef POWER_MEASUREMENT
    #if defined(Board_CC1350_LAUNCHXL)
              Board_DIO30_SWPWR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #endif
    #endif
              PIN_TERMINATE };
    
    /***** Function definitions *****/
    void *mainThread(void *arg0)
    {
    
        potatotrack = 1;
    //    spiParams.frameFormat = SPI_POL1_PHA1; // gets the old alg going
        spiParams.frameFormat = SPI_POL0_PHA1;
    //    potatotrack = 8;
        potatotrack = 2;
        spiParams.mode = SPI_SLAVE;
    //    potatotrack = 9;
    //    spiParams.transferCallbackFxn = transferCompleteFxn;
    //    potatotrack = 10;
    //    spiParams.bitRate = 500000;
        potatotrack = 3;
    //    spiParams.transferMode = SPI_MODE_BLOCKING;
    //    potatotrack = 11;
        potatotrack = 4;
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        potatotrack = 5;
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        potatotrack = 6;
        if (ledPinHandle == NULL)
        {
            while (1)
            {
                potatotrack = 66;
            }
        }
        potatotrack = 7;
        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        potatotrack = 8;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
        potatotrack = 9;
        // Init SPI
        // Set the SPI up for Slave mode
        // and SPI_MODE_BLOCKING.
        slaveSpi = SPI_open(Board_SPI_SLAVE, &spiParams);
        potatotrack = 10;
        /* Request access to the radio */
        rfHandle = RF_open(&rfObject, &RF_prop,
                           (RF_RadioSetup*) &RF_cmdPropRadioDivSetup, &rfParams);
        potatotrack = 11;
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);
        potatotrack = 12;
        while (1)
        {
            memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
            potatotrack = 13;
            transaction.count = SPI_MSG_LENGTH;
            potatotrack = 14;
            transaction.txBuf = (void *) slaveTxBuffer;
            potatotrack = 15;
            transaction.rxBuf = (void *) slaveRxBuffer;
            potatotrack = 16;
            // Read the bytes you want to read over SPI
            SPI_transfer(slaveSpi, &transaction);
            potatotrack = 17;
    
            // Copy the rxBuf to packet
            potatotrack = 18;
            memcpy(packet, slaveRxBuffer, PAYLOAD_LENGTH);
            potatotrack = 19;
            RF_cmdPropTx.pPkt = packet;
            /* Send packet */
            potatotrack = 20;
            RF_runCmd(rfHandle, (RF_Op*) &RF_cmdPropTx, RF_PriorityNormal, NULL, 0);
    
        }
    }

    Please excuse the Potato tracker variable. I had used this to identify where the program gets stuck.

    Here is also SPISlave which I used to sanity check. I have changed some small details in here to get it working well.

    /*
     *  ======== spislave.c ========
     */
    #include <stddef.h>
    #include <stdint.h>
    #include <string.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    #include <semaphore.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SPI.h>
    #include <ti/display/Display.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #define THREADSTACKSIZE (1024)
    
    #define SPI_MSG_LENGTH  (40)
    #define SLAVE_MSG       ("123456 ")
    
    #define MAX_LOOP        (1000)
    int potatotrack = 0;
    static Display_Handle display;
    
    unsigned char slaveRxBuffer[SPI_MSG_LENGTH];
    unsigned char slaveTxBuffer[SPI_MSG_LENGTH];
    
    /* Semaphore to block slave until transfer is complete */
    sem_t slaveSem;
    
    uint16_t phaseBI;
    uint16_t phaseAI;
    uint16_t DCLinkV;
    uint16_t CoilT;
    uint16_t DCLinkI;
    uint16_t AuxT;
    uint16_t BattT;
    
    uint16_t hall1;
    uint16_t hall2;
    uint16_t hall3;
    
    /*
     *  ======== transferCompleteFxn ========
     *  Callback function for SPI_transfer().
     */
    void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction)
    {
        sem_post(&slaveSem);
    }
    
    /*
     * ======== slaveThread ========
     *  Slave SPI sends a message to master while simultaneously receiving a
     *  message from the master.
     */
    void *slaveThread(void *arg0)
    {
        SPI_Handle slaveSpi;
        SPI_Params spiParams;
        SPI_Transaction transaction;
        uint32_t i;
        bool transferOK;
        int32_t status;
        potatotrack = 1;
        /*
         * Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY are GPIO pins connected
         * between the master & slave.  These pins are used to synchronize
         * the master & slave applications via a small 'handshake'.  The pins
         * are later used to synchronize transfers & ensure the master will not
         * start a transfer until the slave is ready.  These pins behave
         * differently between spimaster & spislave examples:
         *
         * spislave example:
         *     * Board_SPI_MASTER_READY is configured as an input pin.  During the
         *       'handshake' this pin is read & a high value will indicate the
         *       master is ready to run the application.  Afterwards, the pin is
         *       read to determine if the master has already opened its SPI pins.
         *       The master will pull this pin low when it has opened its SPI.
         *
         *     * Board_SPI_SLAVE_READY is configured as an output pin.  During the
         *       'handshake' this pin is changed from low to high output.  This
         *       notifies the master the slave is ready to run the application.
         *       Afterwards, the pin is used by the slave to notify the master it
         *       is ready for a transfer.  When ready for a transfer, this pin will
         *       be pulled low.
         *
         * Below we set Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY initial
         * conditions for the 'handshake'.
         */
        GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_INPUT);
        potatotrack = 2;
        /*
         * Handshake - Set Board_SPI_SLAVE_READY high to indicate slave is ready
         * to run.  Wait for Board_SPI_MASTER_READY to be high.
         */
        GPIO_write(Board_SPI_SLAVE_READY, 1);
    //    while (GPIO_read(Board_SPI_MASTER_READY) == 0) {}
        potatotrack = 3;
        /*
         * Create synchronization semaphore; this semaphore will block the slave
         * until a transfer is complete.  The slave is configured in callback mode
         * to allow us to configure the SPI transfer & then notify the master the
         * slave is ready.  However, we must still wait for the current transfer
         * to be complete before setting up the next.  Thus, we wait on slaveSem;
         * once the transfer is complete the callback function will unblock the
         * slave.
         */
        status = sem_init(&slaveSem, 0, 0);
        potatotrack = 4;
        if (status != 0)
        {
    //        Display_printf(display, 0, 0, "Error creating slaveSem\n");
    
            while (1)
                ;
        }
        potatotrack = 5;
    
        /*
         * Wait until master SPI is open.  When the master is configuring SPI pins
         * the clock may toggle from low to high (or high to low depending on
         * polarity).  If using 3-pin SPI & the slave has been opened before the
         * master, clock transitions may cause the slave to shift bits out assuming
         * it is an actual transfer.  We can prevent this behavior by opening the
         * master first & then opening the slave.
         */
    //    while (GPIO_read(Board_SPI_MASTER_READY)) {}
        potatotrack = 6;
        /*
         * Open SPI as slave in callback mode; callback mode is used to allow us to
         * configure the transfer & then set Board_SPI_SLAVE_READY high.
         */
        SPI_Params_init(&spiParams);
        potatotrack = 7;
    //        spiParams.frameFormat = SPI_POL1_PHA0;
        spiParams.frameFormat = SPI_POL1_PHA1; // gets the old alg going
    //    spiParams.frameFormat = SPI_POL0_PHA1;
        potatotrack = 8;
        spiParams.mode = SPI_SLAVE;
        potatotrack = 9;
        spiParams.transferCallbackFxn = transferCompleteFxn;
        potatotrack = 10;
    //    spiParams.bitRate = 500000;
        potatotrack = 111;
        spiParams.transferMode = SPI_MODE_CALLBACK;
        potatotrack = 11;
        slaveSpi = SPI_open(Board_SPI_SLAVE, &spiParams);
        potatotrack = 12;
        if (slaveSpi == NULL)
        {
    //        Display_printf(display, 0, 0, "Error initializing slave SPI\n");
            while (1)
                ;
        }
        else
        {
            Display_printf(display, 0, 0, "Slave SPI initialized\n");
        }
        potatotrack = 13;
    
        /* Copy message to transmit buffer */
        strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH);
        potatotrack = 14;
        i = 0;
    //    memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
    //    for (i = 0; i < MAX_LOOP; i++) {
        while (true)
        {
            /* Initialize slave SPI transaction structure */
    //        slaveTxBuffer[sizeof(SLAVE_MSG) - 1] = (i % 10) + '0';
            potatotrack = 15;
            memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
            potatotrack = 16;
            transaction.count = SPI_MSG_LENGTH;
            potatotrack = 17;
            transaction.txBuf = (void *) slaveTxBuffer;
            potatotrack = 18;
            transaction.rxBuf = (void *) slaveRxBuffer;
            potatotrack = 19;
            /* Toggle on user LED, indicating a SPI transfer is in progress */
            GPIO_toggle(Board_GPIO_LED1);
            potatotrack = 20;
            /*
             * Setup SPI transfer; Board_SPI_SLAVE_READY will be set to notify
             * master the slave is ready.
             */
            transferOK = SPI_transfer(slaveSpi, &transaction);
            potatotrack = 21;
    
            if (transferOK)
            {
                GPIO_write(Board_SPI_SLAVE_READY, 0);
                potatotrack = 211;
    //             Wait until transfer has completed
                sem_wait(&slaveSem);
                potatotrack = 22;
    
    //             * Drive Board_SPI_SLAVE_READY high to indicate slave is not ready
    //             * for another transfer yet.
    
                GPIO_write(Board_SPI_SLAVE_READY, 1);
                potatotrack = 23;
    
                phaseAI = slaveRxBuffer[0] * 256 + slaveRxBuffer[1];
                phaseBI = slaveRxBuffer[2] * 256 + slaveRxBuffer[3];
    
                CoilT = slaveRxBuffer[4] * 256 + slaveRxBuffer[5];
                BattT = slaveRxBuffer[6] * 256 + slaveRxBuffer[7];
                AuxT = slaveRxBuffer[8] * 256 + slaveRxBuffer[9];
    
                hall1 = slaveRxBuffer[10] * 256 + slaveRxBuffer[11];
                hall2 = slaveRxBuffer[12] * 256 + slaveRxBuffer[13];
                hall3 = slaveRxBuffer[14] * 256 + slaveRxBuffer[15];
    
                DCLinkI = slaveRxBuffer[16] * 256 + slaveRxBuffer[17];
                DCLinkV = slaveRxBuffer[18] * 256 + slaveRxBuffer[19];
    //            Display_printf(display, 0, 0, "Slave received: %s", slaveRxBuffer);
            }
            else
            {
    //            Display_printf(display, 0, 0, "Unsuccessful slave SPI transfer");
                potatotrack = 233;
            }
    
            sleep(1);
            i++;
            potatotrack = 24;
        }
    
        SPI_close(slaveSpi);
        Display_printf(display, 0, 0, "Clearing Buffer");
        potatotrack = 25;
        /* Example complete - set pins to a known state */
        GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_write(Board_SPI_SLAVE_READY, 0);
        potatotrack = 26;
        Display_printf(display, 0, 0, "\nDone");
        potatotrack = 27;
        return (NULL);
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        pthread_t thread0;
        pthread_attr_t attrs;
        struct sched_param priParam;
        int retc;
        int detachState;
    
        /* Call driver init functions. */
        Display_init();
        GPIO_init();
        SPI_init();
    
        /* Configure the LED pins */
        GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Open the display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL)
        {
            /* Failed to open display driver */
            while (1)
                ;
        }
    
        /* Turn on user LED */
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        Display_printf(display, 0, 0, "Starting the SPI slave example");
        Display_printf(
                display,
                0,
                0,
                "This example requires external wires to be "
                "connected to the header pins. Please see the Board.html for details.\n");
    
        /* Create application thread */
        pthread_attr_init(&attrs);
    
        detachState = PTHREAD_CREATE_DETACHED;
        /* Set priority and stack size attributes */
        retc = pthread_attr_setdetachstate(&attrs, detachState);
        if (retc != 0)
        {
            /* pthread_attr_setdetachstate() failed */
            while (1)
                ;
        }
    
        retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
        if (retc != 0)
        {
            /* pthread_attr_setstacksize() failed */
            while (1)
                ;
        }
    
        /* Create slave thread */
        priParam.sched_priority = 1;
        pthread_attr_setschedparam(&attrs, &priParam);
    
        retc = pthread_create(&thread0, &attrs, slaveThread, NULL);
        if (retc != 0)
        {
            /* pthread_create() failed */
            while (1)
                ;
        }
    
        return (NULL);
    }
    

    Would you guys happen to have any ideas on how to run the rfPacketTx code past the SPITransfer point?

    Thanks so much!

  • The following code receives 10 bytes over SPI before it transmit it over the air, and starts waiting for another 10 bytes on the SPI:

    #define PAYLOAD_LENGTH 10
    
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    SPI_Handle spiHandle;
    SPI_Transaction spiTransaction;
    
    static uint8_t rfPacket[PAYLOAD_LENGTH];
    static uint8_t spiRxBuffer[PAYLOAD_LENGTH];
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        RF_cmdPropTx.pPkt = rfPacket;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
    
        SPI_Params      spiParams;
        SPI_init();
        SPI_Params_init(&spiParams);
        spiParams.frameFormat = SPI_POL0_PHA1;
        spiParams.mode = SPI_SLAVE;
        spiParams.transferMode = SPI_MODE_BLOCKING;
        spiParams.bitRate = 2000000;
    
        spiHandle = SPI_open(CC1310_LAUNCHXL_SPI0, &spiParams);
    
        spiTransaction.count = PAYLOAD_LENGTH;
        spiTransaction.txBuf = NULL;
        spiTransaction.rxBuf = spiRxBuffer;
    
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        while(1)
        {
            SPI_transfer(spiHandle, &spiTransaction);
            memcpy(rfPacket, spiRxBuffer, PAYLOAD_LENGTH);
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);
        }
    }

    Siri

  • Hi Siri,

    Thanks so much for this, although it seems to work briefly, and then the SPI transaction seems to be cancelled.

    In the end I'd like the entire operation to be continuous regardless of what set of values are sent over SPI to the CC1310 board.

    On another note, while I was using your code, you gave me an idea actually, to fuse bits of your SPISlave function code into the rfPacketTx.c code.

    Below is the resultant that works very briefly. It seems to stop 

    #define PAYLOAD_LENGTH      40
    #ifdef POWER_MEASUREMENT
    #define PACKET_INTERVAL     5  /* For power measurement set packet interval to 5s */
    #else
    #define PACKET_INTERVAL     500000  /* Set packet interval to 500000us or 500ms */
    #endif
    
    #define SPI_MSG_LENGTH  (40)
    #define SLAVE_MSG       ("123456 ")
    /***** Prototypes *****/
    
    //  ======== spislave.c ========
    #include <stdlib.h>
    //#include <unistd.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    //#include <ti/drivers/SPI.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    //#include "Board.h"
    #include "smartrf_settings/smartrf_settings.h"
    //#include "RFQueue.c"
    
    #include <stddef.h>
    #include <stdint.h>
    #include <string.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    #include <semaphore.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SPI.h>
    #include <ti/display/Display.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #define THREADSTACKSIZE (1024)
    
    #define SPI_MSG_LENGTH  (40)
    #define SLAVE_MSG       ("123456 ")
    
    #define MAX_LOOP        (1000)
    int potatotrack = 0;
    static Display_Handle display;
    
    unsigned char slaveRxBuffer[SPI_MSG_LENGTH];
    unsigned char slaveTxBuffer[SPI_MSG_LENGTH];
    
    /* Semaphore to block slave until transfer is complete */
    sem_t slaveSem;
    
    uint16_t phaseBI;
    uint16_t phaseAI;
    uint16_t DCLinkV;
    uint16_t CoilT;
    uint16_t DCLinkI;
    uint16_t AuxT;
    uint16_t BattT;
    
    uint16_t hall1;
    uint16_t hall2;
    uint16_t hall3;
    
    
    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 uint16_t seqNumber;
    
    
    
    
    /*
    
     * 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,
    #ifdef POWER_MEASUREMENT
    #if defined(Board_CC1350_LAUNCHXL)
              Board_DIO30_SWPWR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #endif
    #endif
              PIN_TERMINATE };
    
    /*
     *  ======== transferCompleteFxn ========
     *  Callback function for SPI_transfer().
     */
    void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction)
    {
        sem_post(&slaveSem);
    }
    
    /*
     * ======== slaveThread ========
     *  Slave SPI sends a message to master while simultaneously receiving a
     *  message from the master.
     */
    void *slaveThread(void *arg0)
    {
        SPI_Handle slaveSpi;
        SPI_Params spiParams;
        SPI_Transaction transaction;
        uint32_t i;
        bool transferOK;
        int32_t status;
        potatotrack = 1;
        /*
         * Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY are GPIO pins connected
         * between the master & slave.  These pins are used to synchronize
         * the master & slave applications via a small 'handshake'.  The pins
         * are later used to synchronize transfers & ensure the master will not
         * start a transfer until the slave is ready.  These pins behave
         * differently between spimaster & spislave examples:
         *
         * spislave example:
         *     * Board_SPI_MASTER_READY is configured as an input pin.  During the
         *       'handshake' this pin is read & a high value will indicate the
         *       master is ready to run the application.  Afterwards, the pin is
         *       read to determine if the master has already opened its SPI pins.
         *       The master will pull this pin low when it has opened its SPI.
         *
         *     * Board_SPI_SLAVE_READY is configured as an output pin.  During the
         *       'handshake' this pin is changed from low to high output.  This
         *       notifies the master the slave is ready to run the application.
         *       Afterwards, the pin is used by the slave to notify the master it
         *       is ready for a transfer.  When ready for a transfer, this pin will
         *       be pulled low.
         *
         * Below we set Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY initial
         * conditions for the 'handshake'.
         */
        GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_INPUT);
        potatotrack = 2;
        /*
         * Handshake - Set Board_SPI_SLAVE_READY high to indicate slave is ready
         * to run.  Wait for Board_SPI_MASTER_READY to be high.
         */
        GPIO_write(Board_SPI_SLAVE_READY, 1);
    //    while (GPIO_read(Board_SPI_MASTER_READY) == 0) {}
        potatotrack = 3;
        /*
         * Create synchronization semaphore; this semaphore will block the slave
         * until a transfer is complete.  The slave is configured in callback mode
         * to allow us to configure the SPI transfer & then notify the master the
         * slave is ready.  However, we must still wait for the current transfer
         * to be complete before setting up the next.  Thus, we wait on slaveSem;
         * once the transfer is complete the callback function will unblock the
         * slave.
         */
        status = sem_init(&slaveSem, 0, 0);
        potatotrack = 4;
        if (status != 0)
        {
    //        Display_printf(display, 0, 0, "Error creating slaveSem\n");
    
            while (1)
                ;
        }
        potatotrack = 5;
    
        /*
         * Wait until master SPI is open.  When the master is configuring SPI pins
         * the clock may toggle from low to high (or high to low depending on
         * polarity).  If using 3-pin SPI & the slave has been opened before the
         * master, clock transitions may cause the slave to shift bits out assuming
         * it is an actual transfer.  We can prevent this behavior by opening the
         * master first & then opening the slave.
         */
    //    while (GPIO_read(Board_SPI_MASTER_READY)) {}
        potatotrack = 6;
        /*
         * Open SPI as slave in callback mode; callback mode is used to allow us to
         * configure the transfer & then set Board_SPI_SLAVE_READY high.
         */
        SPI_Params_init(&spiParams);
        potatotrack = 7;
    //        spiParams.frameFormat = SPI_POL1_PHA0;
        spiParams.frameFormat = SPI_POL1_PHA1; // gets the old alg going
    //    spiParams.frameFormat = SPI_POL0_PHA1;
        potatotrack = 8;
        spiParams.mode = SPI_SLAVE;
        potatotrack = 9;
        spiParams.transferCallbackFxn = transferCompleteFxn;
        potatotrack = 10;
    //    spiParams.bitRate = 500000;
        potatotrack = 111;
        spiParams.transferMode = SPI_MODE_CALLBACK;
        potatotrack = 11;
        slaveSpi = SPI_open(Board_SPI_SLAVE, &spiParams);
        potatotrack = 12;
        if (slaveSpi == NULL)
        {
    //        Display_printf(display, 0, 0, "Error initializing slave SPI\n");
            while (1)
                ;
        }
        else
        {
            Display_printf(display, 0, 0, "Slave SPI initialized\n");
        }
        potatotrack = 13;
    
        /* Copy message to transmit buffer */
        strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH);
        potatotrack = 14;
        i = 0;
    //    memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
    //    for (i = 0; i < MAX_LOOP; i++) {
        while (true)
        {
            /* Initialize slave SPI transaction structure */
    //        slaveTxBuffer[sizeof(SLAVE_MSG) - 1] = (i % 10) + '0';
            potatotrack = 15;
            memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
            potatotrack = 16;
            transaction.count = SPI_MSG_LENGTH;
            potatotrack = 17;
            transaction.txBuf = (void *) slaveTxBuffer;
            potatotrack = 18;
            transaction.rxBuf = (void *) slaveRxBuffer;
            potatotrack = 19;
            /* Toggle on user LED, indicating a SPI transfer is in progress */
            GPIO_toggle(Board_GPIO_LED1);
            potatotrack = 20;
    
    
    
    
            RF_Params rfParams;
            RF_Params_init(&rfParams);
    
            potatotrack = 51;
            /* Open LED pins */
    //        ledPinHandle = PIN_open(&ledPinState, pinTable);
    //        potatotrack = 61;
    //        if (ledPinHandle == NULL)
    //        {
    //            while (1)
    //            {
    //                potatotrack = 661;
    //            }
    //        }
            potatotrack = 71;
            RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
            potatotrack = 81;
            RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
            potatotrack = 91;
            // Init SPI
            // Set the SPI up for Slave mode
            // and SPI_MODE_BLOCKING.
                    potatotrack = 101;
            /* Request access to the radio */
            rfHandle = RF_open(&rfObject, &RF_prop,
                               (RF_RadioSetup*) &RF_cmdPropRadioDivSetup,
                               &rfParams);
            potatotrack = 111;
            /* Set the frequency */
            RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);
            potatotrack = 12;
    
    
    //
    //        while (1)
    //        {
    //            memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
    //            potatotrack = 13;
    //            transaction.count = SPI_MSG_LENGTH;
    //            potatotrack = 14;
    //            transaction.txBuf = (void *) slaveTxBuffer;
    //            potatotrack = 15;
    //            transaction.rxBuf = (void *) slaveRxBuffer;
    //            potatotrack = 16;
    //            // Read the bytes you want to read over SPI
    //
    //
    //        }
    
            /*
             * Setup SPI transfer; Board_SPI_SLAVE_READY will be set to notify
             * master the slave is ready.
             */
            transferOK = SPI_transfer(slaveSpi, &transaction);
            potatotrack = 21;
    
            if (transferOK)
            {
                GPIO_write(Board_SPI_SLAVE_READY, 0);
                potatotrack = 211;
    //             Wait until transfer has completed
                sem_wait(&slaveSem);
                potatotrack = 22;
    
    //             * Drive Board_SPI_SLAVE_READY high to indicate slave is not ready
    //             * for another transfer yet.
    
                GPIO_write(Board_SPI_SLAVE_READY, 1);
                potatotrack = 23;
    
                phaseAI = slaveRxBuffer[0] * 256 + slaveRxBuffer[1];
                phaseBI = slaveRxBuffer[2] * 256 + slaveRxBuffer[3];
    
                CoilT = slaveRxBuffer[4] * 256 + slaveRxBuffer[5];
                BattT = slaveRxBuffer[6] * 256 + slaveRxBuffer[7];
                AuxT = slaveRxBuffer[8] * 256 + slaveRxBuffer[9];
    
                hall1 = slaveRxBuffer[10] * 256 + slaveRxBuffer[11];
                hall2 = slaveRxBuffer[12] * 256 + slaveRxBuffer[13];
                hall3 = slaveRxBuffer[14] * 256 + slaveRxBuffer[15];
    
                DCLinkI = slaveRxBuffer[16] * 256 + slaveRxBuffer[17];
                DCLinkV = slaveRxBuffer[18] * 256 + slaveRxBuffer[19];
    //            Display_printf(display, 0, 0, "Slave received: %s", slaveRxBuffer);
    
    
    
    
    
    
                potatotrack = 17;
    
                // Copy the rxBuf to packet
                potatotrack = 18;
                memcpy(packet, slaveRxBuffer, PAYLOAD_LENGTH);
                potatotrack = 19;
                RF_cmdPropTx.pPkt = packet;
                /* Send packet */
                potatotrack = 20;
                RF_runCmd(rfHandle, (RF_Op*) &RF_cmdPropTx, RF_PriorityNormal, NULL,
                          0);
            }
            else
            {
    //            Display_printf(display, 0, 0, "Unsuccessful slave SPI transfer");
                potatotrack = 233;
            }
    
            sleep(1);
            i++;
            potatotrack = 24;
        }
    
        SPI_close(slaveSpi);
        Display_printf(display, 0, 0, "Clearing Buffer");
        potatotrack = 25;
        /* Example complete - set pins to a known state */
        GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_write(Board_SPI_SLAVE_READY, 0);
        potatotrack = 26;
        Display_printf(display, 0, 0, "\nDone");
        potatotrack = 27;
        return (NULL);
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        pthread_t thread0;
        pthread_attr_t attrs;
        struct sched_param priParam;
        int retc;
        int detachState;
    
        /* Call driver init functions. */
        Display_init();
        GPIO_init();
        SPI_init();
    
        /* Configure the LED pins */
        GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Open the display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL)
        {
            /* Failed to open display driver */
            while (1)
                ;
        }
    
        /* Turn on user LED */
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        Display_printf(display, 0, 0, "Starting the SPI slave example");
        Display_printf(
                display,
                0,
                0,
                "This example requires external wires to be "
                "connected to the header pins. Please see the Board.html for details.\n");
    
        /* Create application thread */
        pthread_attr_init(&attrs);
    
        detachState = PTHREAD_CREATE_DETACHED;
        /* Set priority and stack size attributes */
        retc = pthread_attr_setdetachstate(&attrs, detachState);
        if (retc != 0)
        {
            /* pthread_attr_setdetachstate() failed */
            while (1)
                ;
        }
    
        retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
        if (retc != 0)
        {
            /* pthread_attr_setstacksize() failed */
            while (1)
                ;
        }
    
        /* Create slave thread */
        priParam.sched_priority = 1;
        pthread_attr_setschedparam(&attrs, &priParam);
    
        retc = pthread_create(&thread0, &attrs, slaveThread, NULL);
        if (retc != 0)
        {
            /* pthread_create() failed */
            while (1)
                ;
        }
    
        return (NULL);
    }

    Would you happen to have any ideas on what this might be because of and how this can be made to be continuous?

    Thank you sooooo much for your ongoing help!

    #define PAYLOAD_LENGTH      40#ifdef POWER_MEASUREMENT#define PACKET_INTERVAL     5  /* For power measurement set packet interval to 5s */#else#define PACKET_INTERVAL     500000  /* Set packet interval to 500000us or 500ms */#endif
    #define SPI_MSG_LENGTH  (40)#define SLAVE_MSG       ("123456 ")/***** Prototypes *****/
    //  ======== spislave.c ========#include <stdlib.h>//#include <unistd.h>
    /* TI Drivers */#include <ti/drivers/rf/RF.h>#include <ti/drivers/PIN.h>#include <ti/drivers/pin/PINCC26XX.h>//#include <ti/drivers/SPI.h>
    /* Driverlib Header files */#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    /* Board Header files *///#include "Board.h"#include "smartrf_settings/smartrf_settings.h"//#include "RFQueue.c"
    #include <stddef.h>#include <stdint.h>#include <string.h>
    /* POSIX Header files */#include <pthread.h>#include <semaphore.h>#include <unistd.h>
    /* Driver Header files */#include <ti/drivers/GPIO.h>#include <ti/drivers/SPI.h>#include <ti/display/Display.h>
    /* Example/Board Header files */#include "Board.h"
    #define THREADSTACKSIZE (1024)
    #define SPI_MSG_LENGTH  (40)#define SLAVE_MSG       ("123456 ")
    #define MAX_LOOP        (1000)int potatotrack = 0;static Display_Handle display;
    unsigned char slaveRxBuffer[SPI_MSG_LENGTH];unsigned char slaveTxBuffer[SPI_MSG_LENGTH];
    /* Semaphore to block slave until transfer is complete */sem_t slaveSem;
    uint16_t phaseBI;uint16_t phaseAI;uint16_t DCLinkV;uint16_t CoilT;uint16_t DCLinkI;uint16_t AuxT;uint16_t BattT;
    uint16_t hall1;uint16_t hall2;uint16_t hall3;

    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 uint16_t seqNumber;



    /*
     * 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,#ifdef POWER_MEASUREMENT#if defined(Board_CC1350_LAUNCHXL)          Board_DIO30_SWPWR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,#endif#endif          PIN_TERMINATE };
    /* *  ======== transferCompleteFxn ======== *  Callback function for SPI_transfer(). */void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction){    sem_post(&slaveSem);}
    /* * ======== slaveThread ======== *  Slave SPI sends a message to master while simultaneously receiving a *  message from the master. */void *slaveThread(void *arg0){    SPI_Handle slaveSpi;    SPI_Params spiParams;    SPI_Transaction transaction;    uint32_t i;    bool transferOK;    int32_t status;    potatotrack = 1;    /*     * Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY are GPIO pins connected     * between the master & slave.  These pins are used to synchronize     * the master & slave applications via a small 'handshake'.  The pins     * are later used to synchronize transfers & ensure the master will not     * start a transfer until the slave is ready.  These pins behave     * differently between spimaster & spislave examples:     *     * spislave example:     *     * Board_SPI_MASTER_READY is configured as an input pin.  During the     *       'handshake' this pin is read & a high value will indicate the     *       master is ready to run the application.  Afterwards, the pin is     *       read to determine if the master has already opened its SPI pins.     *       The master will pull this pin low when it has opened its SPI.     *     *     * Board_SPI_SLAVE_READY is configured as an output pin.  During the     *       'handshake' this pin is changed from low to high output.  This     *       notifies the master the slave is ready to run the application.     *       Afterwards, the pin is used by the slave to notify the master it     *       is ready for a transfer.  When ready for a transfer, this pin will     *       be pulled low.     *     * Below we set Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY initial     * conditions for the 'handshake'.     */    GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);    GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_INPUT);    potatotrack = 2;    /*     * Handshake - Set Board_SPI_SLAVE_READY high to indicate slave is ready     * to run.  Wait for Board_SPI_MASTER_READY to be high.     */    GPIO_write(Board_SPI_SLAVE_READY, 1);//    while (GPIO_read(Board_SPI_MASTER_READY) == 0) {}    potatotrack = 3;    /*     * Create synchronization semaphore; this semaphore will block the slave     * until a transfer is complete.  The slave is configured in callback mode     * to allow us to configure the SPI transfer & then notify the master the     * slave is ready.  However, we must still wait for the current transfer     * to be complete before setting up the next.  Thus, we wait on slaveSem;     * once the transfer is complete the callback function will unblock the     * slave.     */    status = sem_init(&slaveSem, 0, 0);    potatotrack = 4;    if (status != 0)    {//        Display_printf(display, 0, 0, "Error creating slaveSem\n");
            while (1)            ;    }    potatotrack = 5;
        /*     * Wait until master SPI is open.  When the master is configuring SPI pins     * the clock may toggle from low to high (or high to low depending on     * polarity).  If using 3-pin SPI & the slave has been opened before the     * master, clock transitions may cause the slave to shift bits out assuming     * it is an actual transfer.  We can prevent this behavior by opening the     * master first & then opening the slave.     *///    while (GPIO_read(Board_SPI_MASTER_READY)) {}    potatotrack = 6;    /*     * Open SPI as slave in callback mode; callback mode is used to allow us to     * configure the transfer & then set Board_SPI_SLAVE_READY high.     */    SPI_Params_init(&spiParams);    potatotrack = 7;//        spiParams.frameFormat = SPI_POL1_PHA0;    spiParams.frameFormat = SPI_POL1_PHA1; // gets the old alg going//    spiParams.frameFormat = SPI_POL0_PHA1;    potatotrack = 8;    spiParams.mode = SPI_SLAVE;    potatotrack = 9;    spiParams.transferCallbackFxn = transferCompleteFxn;    potatotrack = 10;//    spiParams.bitRate = 500000;    potatotrack = 111;    spiParams.transferMode = SPI_MODE_CALLBACK;    potatotrack = 11;    slaveSpi = SPI_open(Board_SPI_SLAVE, &spiParams);    potatotrack = 12;    if (slaveSpi == NULL)    {//        Display_printf(display, 0, 0, "Error initializing slave SPI\n");        while (1)            ;    }    else    {        Display_printf(display, 0, 0, "Slave SPI initialized\n");    }    potatotrack = 13;
        /* Copy message to transmit buffer */    strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH);    potatotrack = 14;    i = 0;//    memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);//    for (i = 0; i < MAX_LOOP; i++) {    while (true)    {        /* Initialize slave SPI transaction structure *///        slaveTxBuffer[sizeof(SLAVE_MSG) - 1] = (i % 10) + '0';        potatotrack = 15;        memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);        potatotrack = 16;        transaction.count = SPI_MSG_LENGTH;        potatotrack = 17;        transaction.txBuf = (void *) slaveTxBuffer;        potatotrack = 18;        transaction.rxBuf = (void *) slaveRxBuffer;        potatotrack = 19;        /* Toggle on user LED, indicating a SPI transfer is in progress */        GPIO_toggle(Board_GPIO_LED1);        potatotrack = 20;



            RF_Params rfParams;        RF_Params_init(&rfParams);
            potatotrack = 51;        /* Open LED pins *///        ledPinHandle = PIN_open(&ledPinState, pinTable);//        potatotrack = 61;//        if (ledPinHandle == NULL)//        {//            while (1)//            {//                potatotrack = 661;//            }//        }        potatotrack = 71;        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;        potatotrack = 81;        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;        potatotrack = 91;        // Init SPI        // Set the SPI up for Slave mode        // and SPI_MODE_BLOCKING.                potatotrack = 101;        /* Request access to the radio */        rfHandle = RF_open(&rfObject, &RF_prop,                           (RF_RadioSetup*) &RF_cmdPropRadioDivSetup,                           &rfParams);        potatotrack = 111;        /* Set the frequency */        RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);        potatotrack = 12;

    ////        while (1)//        {//            memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);//            potatotrack = 13;//            transaction.count = SPI_MSG_LENGTH;//            potatotrack = 14;//            transaction.txBuf = (void *) slaveTxBuffer;//            potatotrack = 15;//            transaction.rxBuf = (void *) slaveRxBuffer;//            potatotrack = 16;//            // Read the bytes you want to read over SPI//////        }
            /*         * Setup SPI transfer; Board_SPI_SLAVE_READY will be set to notify         * master the slave is ready.         */        transferOK = SPI_transfer(slaveSpi, &transaction);        potatotrack = 21;
            if (transferOK)        {            GPIO_write(Board_SPI_SLAVE_READY, 0);            potatotrack = 211;//             Wait until transfer has completed            sem_wait(&slaveSem);            potatotrack = 22;
    //             * Drive Board_SPI_SLAVE_READY high to indicate slave is not ready//             * for another transfer yet.
                GPIO_write(Board_SPI_SLAVE_READY, 1);            potatotrack = 23;
                phaseAI = slaveRxBuffer[0] * 256 + slaveRxBuffer[1];            phaseBI = slaveRxBuffer[2] * 256 + slaveRxBuffer[3];
                CoilT = slaveRxBuffer[4] * 256 + slaveRxBuffer[5];            BattT = slaveRxBuffer[6] * 256 + slaveRxBuffer[7];            AuxT = slaveRxBuffer[8] * 256 + slaveRxBuffer[9];
                hall1 = slaveRxBuffer[10] * 256 + slaveRxBuffer[11];            hall2 = slaveRxBuffer[12] * 256 + slaveRxBuffer[13];            hall3 = slaveRxBuffer[14] * 256 + slaveRxBuffer[15];
                DCLinkI = slaveRxBuffer[16] * 256 + slaveRxBuffer[17];            DCLinkV = slaveRxBuffer[18] * 256 + slaveRxBuffer[19];//            Display_printf(display, 0, 0, "Slave received: %s", slaveRxBuffer);





                potatotrack = 17;
                // Copy the rxBuf to packet            potatotrack = 18;            memcpy(packet, slaveRxBuffer, PAYLOAD_LENGTH);            potatotrack = 19;            RF_cmdPropTx.pPkt = packet;            /* Send packet */            potatotrack = 20;            RF_runCmd(rfHandle, (RF_Op*) &RF_cmdPropTx, RF_PriorityNormal, NULL,                      0);        }        else        {//            Display_printf(display, 0, 0, "Unsuccessful slave SPI transfer");            potatotrack = 233;        }
            sleep(1);        i++;        potatotrack = 24;    }
        SPI_close(slaveSpi);    Display_printf(display, 0, 0, "Clearing Buffer");    potatotrack = 25;    /* Example complete - set pins to a known state */    GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);    GPIO_write(Board_SPI_SLAVE_READY, 0);    potatotrack = 26;    Display_printf(display, 0, 0, "\nDone");    potatotrack = 27;    return (NULL);}
    /* *  ======== mainThread ======== */void *mainThread(void *arg0){    pthread_t thread0;    pthread_attr_t attrs;    struct sched_param priParam;    int retc;    int detachState;
        /* Call driver init functions. */    Display_init();    GPIO_init();    SPI_init();
        /* Configure the LED pins */    GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);    GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        /* Open the display for output */    display = Display_open(Display_Type_UART, NULL);    if (display == NULL)    {        /* Failed to open display driver */        while (1)            ;    }
        /* Turn on user LED */    GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
        Display_printf(display, 0, 0, "Starting the SPI slave example");    Display_printf(            display,            0,            0,            "This example requires external wires to be "            "connected to the header pins. Please see the Board.html for details.\n");
        /* Create application thread */    pthread_attr_init(&attrs);
        detachState = PTHREAD_CREATE_DETACHED;    /* Set priority and stack size attributes */    retc = pthread_attr_setdetachstate(&attrs, detachState);    if (retc != 0)    {        /* pthread_attr_setdetachstate() failed */        while (1)            ;    }
        retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);    if (retc != 0)    {        /* pthread_attr_setstacksize() failed */        while (1)            ;    }
        /* Create slave thread */    priParam.sched_priority = 1;    pthread_attr_setschedparam(&attrs, &priParam);
        retc = pthread_create(&thread0, &attrs, slaveThread, NULL);    if (retc != 0)    {        /* pthread_create() failed */        while (1)            ;    }
        return (NULL);}

  • I assume that you are communicating with another SPI slave that is not a CC1310. Is that correct?

    it is unfortunately not possible for me to know what the problem is on the slave side, when I do not have the master side to test with.

    If we shall be able to help you any further you need to make a dummy master running on a second LP that do the same thing as the real SPI  master.

    If we have both the master and the slave code up and running on two LP we can test the code, and maybe figure out what is going on, but this is hard to figure out when we do not have any way to re-create the problems you are seeing.

    BR

    Siri

  • Hi Siri,

    Oh I'm sorry for not providing you with the context!

    So what I'm doing is I'm using a TMS320F28379D Launchpad to communicate ADC measured values, to a CC1310 over SPI.

    I then want the CC1310 to transmit these ADC measured values over RF to another CC1310, who will relay these ADC values onwards to another TMS320F28379D. Pictured below is what I'm trying to achieve.

    Each square is a different microcontroller which performs a different set of communication instructions. 

    The F28379D on the Secondary side currently measures values using some ADCs and communicates these values over SPI continuously.

    The CC1310 on the Secondary side is almost able to Receive these values and send them straight off over RF simultaneously, however the entire program seems to hang after one round.

    On the F28379D, attached here is the code that I use:

    SECONDARY_MASTER_V2_spi_loopback_cpu01.zip

    On the CC1310, I use the following code:

    #define PAYLOAD_LENGTH      100
    #ifdef POWER_MEASUREMENT
    #define PACKET_INTERVAL     5  /* For power measurement set packet interval to 5s */
    #else
    #define PACKET_INTERVAL     500000  /* Set packet interval to 500000us or 500ms */
    #endif
    
    #define SPI_MSG_LENGTH  (40)
    #define SLAVE_MSG       ("123456 ")
    /***** Prototypes *****/
    
    //  ======== spislave.c ========
    #include <stdlib.h>
    //#include <unistd.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    //#include <ti/drivers/SPI.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    //#include "Board.h"
    #include "smartrf_settings/smartrf_settings.h"
    //#include "RFQueue.c"
    
    #include <stddef.h>
    #include <stdint.h>
    #include <string.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    #include <semaphore.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SPI.h>
    #include <ti/display/Display.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #define THREADSTACKSIZE (1024)
    
    #define SPI_MSG_LENGTH  (40)
    #define SLAVE_MSG       ("123456 ")
    
    #define MAX_LOOP        (1000)
    int potatotrack = 0;
    static Display_Handle display;
    
    unsigned char slaveRxBuffer[SPI_MSG_LENGTH];
    unsigned char slaveTxBuffer[SPI_MSG_LENGTH];
    
    /* Semaphore to block slave until transfer is complete */
    sem_t slaveSem;
    
    uint16_t phaseBI;
    uint16_t phaseAI;
    uint16_t DCLinkV;
    uint16_t CoilT;
    uint16_t DCLinkI;
    uint16_t AuxT;
    uint16_t BattT;
    
    uint16_t hall1;
    uint16_t hall2;
    uint16_t hall3;
    
    
    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 uint16_t seqNumber;
    
    
    
    
    /*
    
     * 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,
    #ifdef POWER_MEASUREMENT
    #if defined(Board_CC1350_LAUNCHXL)
              Board_DIO30_SWPWR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    #endif
    #endif
              PIN_TERMINATE };
    
    /*
     *  ======== transferCompleteFxn ========
     *  Callback function for SPI_transfer().
     */
    void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction)
    {
        sem_post(&slaveSem);
    }
    
    /*
     * ======== slaveThread ========
     *  Slave SPI sends a message to master while simultaneously receiving a
     *  message from the master.
     */
    void *slaveThread(void *arg0)
    {
        SPI_Handle slaveSpi;
        SPI_Params spiParams;
        SPI_Transaction transaction;
        uint32_t i;
        bool transferOK;
        int32_t status;
        potatotrack = 1;
        /*
         * Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY are GPIO pins connected
         * between the master & slave.  These pins are used to synchronize
         * the master & slave applications via a small 'handshake'.  The pins
         * are later used to synchronize transfers & ensure the master will not
         * start a transfer until the slave is ready.  These pins behave
         * differently between spimaster & spislave examples:
         *
         * spislave example:
         *     * Board_SPI_MASTER_READY is configured as an input pin.  During the
         *       'handshake' this pin is read & a high value will indicate the
         *       master is ready to run the application.  Afterwards, the pin is
         *       read to determine if the master has already opened its SPI pins.
         *       The master will pull this pin low when it has opened its SPI.
         *
         *     * Board_SPI_SLAVE_READY is configured as an output pin.  During the
         *       'handshake' this pin is changed from low to high output.  This
         *       notifies the master the slave is ready to run the application.
         *       Afterwards, the pin is used by the slave to notify the master it
         *       is ready for a transfer.  When ready for a transfer, this pin will
         *       be pulled low.
         *
         * Below we set Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY initial
         * conditions for the 'handshake'.
         */
        GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_INPUT);
        potatotrack = 2;
        /*
         * Handshake - Set Board_SPI_SLAVE_READY high to indicate slave is ready
         * to run.  Wait for Board_SPI_MASTER_READY to be high.
         */
        GPIO_write(Board_SPI_SLAVE_READY, 1);
    //    while (GPIO_read(Board_SPI_MASTER_READY) == 0) {}
        potatotrack = 3;
        /*
         * Create synchronization semaphore; this semaphore will block the slave
         * until a transfer is complete.  The slave is configured in callback mode
         * to allow us to configure the SPI transfer & then notify the master the
         * slave is ready.  However, we must still wait for the current transfer
         * to be complete before setting up the next.  Thus, we wait on slaveSem;
         * once the transfer is complete the callback function will unblock the
         * slave.
         */
        status = sem_init(&slaveSem, 0, 0);
        potatotrack = 4;
        if (status != 0)
        {
    //        Display_printf(display, 0, 0, "Error creating slaveSem\n");
    
            while (1)
                ;
        }
        potatotrack = 5;
    
        /*
         * Wait until master SPI is open.  When the master is configuring SPI pins
         * the clock may toggle from low to high (or high to low depending on
         * polarity).  If using 3-pin SPI & the slave has been opened before the
         * master, clock transitions may cause the slave to shift bits out assuming
         * it is an actual transfer.  We can prevent this behavior by opening the
         * master first & then opening the slave.
         */
    //    while (GPIO_read(Board_SPI_MASTER_READY)) {}
        potatotrack = 6;
        /*
         * Open SPI as slave in callback mode; callback mode is used to allow us to
         * configure the transfer & then set Board_SPI_SLAVE_READY high.
         */
        SPI_Params_init(&spiParams);
        potatotrack = 7;
    //        spiParams.frameFormat = SPI_POL1_PHA0;
        spiParams.frameFormat = SPI_POL1_PHA1; // gets the old alg going
    //    spiParams.frameFormat = SPI_POL0_PHA1;
        potatotrack = 8;
        spiParams.mode = SPI_SLAVE;
        potatotrack = 9;
    //    spiParams.transferCallbackFxn = transferCompleteFxn;
        potatotrack = 10;
    //    spiParams.bitRate = 500000;
        potatotrack = 111;
    //    spiParams.transferMode = SPI_MODE_CALLBACK;
        potatotrack = 11;
        slaveSpi = SPI_open(Board_SPI_SLAVE, &spiParams);
        potatotrack = 12;
        if (slaveSpi == NULL)
        {
    //        Display_printf(display, 0, 0, "Error initializing slave SPI\n");
            while (1)
                ;
        }
        else
        {
            Display_printf(display, 0, 0, "Slave SPI initialized\n");
        }
        potatotrack = 13;
    
        /* Copy message to transmit buffer */
        strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH);
        potatotrack = 14;
        i = 0;
    //    memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
    //    for (i = 0; i < MAX_LOOP; i++) {
        while (true)
        {
            /* Initialize slave SPI transaction structure */
    //        slaveTxBuffer[sizeof(SLAVE_MSG) - 1] = (i % 10) + '0';
            potatotrack = 15;
            memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
            potatotrack = 16;
            transaction.count = SPI_MSG_LENGTH;
            potatotrack = 17;
            transaction.txBuf = (void *) slaveTxBuffer;
            potatotrack = 18;
            transaction.rxBuf = (void *) slaveRxBuffer;
            potatotrack = 19;
            /* Toggle on user LED, indicating a SPI transfer is in progress */
            GPIO_toggle(Board_GPIO_LED1);
            potatotrack = 20;
    
    
    
    
            RF_Params rfParams;
            RF_Params_init(&rfParams);
    
            potatotrack = 51;
            /* Open LED pins */
    //        ledPinHandle = PIN_open(&ledPinState, pinTable);
    //        potatotrack = 61;
    //        if (ledPinHandle == NULL)
    //        {
    //            while (1)
    //            {
    //                potatotrack = 661;
    //            }
    //        }
            potatotrack = 71;
            RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
            potatotrack = 81;
            RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
            potatotrack = 91;
            // Init SPI
            // Set the SPI up for Slave mode
            // and SPI_MODE_BLOCKING.
                    potatotrack = 101;
            /* Request access to the radio */
            rfHandle = RF_open(&rfObject, &RF_prop,
                               (RF_RadioSetup*) &RF_cmdPropRadioDivSetup,
                               &rfParams);
            potatotrack = 111;
            /* Set the frequency */
            RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);
            potatotrack = 12;
    
    
    //
    //        while (1)
    //        {
    //            memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
    //            potatotrack = 13;
    //            transaction.count = SPI_MSG_LENGTH;
    //            potatotrack = 14;
    //            transaction.txBuf = (void *) slaveTxBuffer;
    //            potatotrack = 15;
    //            transaction.rxBuf = (void *) slaveRxBuffer;
    //            potatotrack = 16;
    //            // Read the bytes you want to read over SPI
    //
    //
    //        }
    
            /*
             * Setup SPI transfer; Board_SPI_SLAVE_READY will be set to notify
             * master the slave is ready.
             */
            transferOK = SPI_transfer(slaveSpi, &transaction);
            potatotrack = 21;
    
            if (transferOK)
            {
                GPIO_write(Board_SPI_SLAVE_READY, 0);
                potatotrack = 211;
    //             Wait until transfer has completed
    //            sem_wait(&slaveSem);
                potatotrack = 22;
    
    //             * Drive Board_SPI_SLAVE_READY high to indicate slave is not ready
    //             * for another transfer yet.
    
                GPIO_write(Board_SPI_SLAVE_READY, 1);
                potatotrack = 23;
    
                phaseAI = slaveRxBuffer[0] * 256 + slaveRxBuffer[1];
                phaseBI = slaveRxBuffer[2] * 256 + slaveRxBuffer[3];
    
                CoilT = slaveRxBuffer[4] * 256 + slaveRxBuffer[5];
                BattT = slaveRxBuffer[6] * 256 + slaveRxBuffer[7];
                AuxT = slaveRxBuffer[8] * 256 + slaveRxBuffer[9];
    
                hall1 = slaveRxBuffer[10] * 256 + slaveRxBuffer[11];
                hall2 = slaveRxBuffer[12] * 256 + slaveRxBuffer[13];
                hall3 = slaveRxBuffer[14] * 256 + slaveRxBuffer[15];
    
                DCLinkI = slaveRxBuffer[16] * 256 + slaveRxBuffer[17];
                DCLinkV = slaveRxBuffer[18] * 256 + slaveRxBuffer[19];
    //            Display_printf(display, 0, 0, "Slave received: %s", slaveRxBuffer);
    
    
    
    
    
    
                potatotrack = 17;
    
                // Copy the rxBuf to packet
                potatotrack = 18;
                memcpy(packet, slaveRxBuffer, PAYLOAD_LENGTH);
                potatotrack = 19;
                RF_cmdPropTx.pPkt = packet;
                /* Send packet */
                potatotrack = 20;
                RF_runCmd(rfHandle, (RF_Op*) &RF_cmdPropTx, RF_PriorityNormal, NULL,
                          0);
            }
            else
            {
    //            Display_printf(display, 0, 0, "Unsuccessful slave SPI transfer");
                potatotrack = 233;
            }
    
            sleep(1);
            i++;
            potatotrack = 24;
        }
    
        SPI_close(slaveSpi);
        Display_printf(display, 0, 0, "Clearing Buffer");
        potatotrack = 25;
        /* Example complete - set pins to a known state */
        GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_write(Board_SPI_SLAVE_READY, 0);
        potatotrack = 26;
        Display_printf(display, 0, 0, "\nDone");
        potatotrack = 27;
        return (NULL);
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        pthread_t thread0;
        pthread_attr_t attrs;
        struct sched_param priParam;
        int retc;
        int detachState;
    
        /* Call driver init functions. */
        Display_init();
        GPIO_init();
        SPI_init();
    
        /* Configure the LED pins */
        GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Open the display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL)
        {
            /* Failed to open display driver */
            while (1)
                ;
        }
    
        /* Turn on user LED */
        GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
        Display_printf(display, 0, 0, "Starting the SPI slave example");
        Display_printf(
                display,
                0,
                0,
                "This example requires external wires to be "
                "connected to the header pins. Please see the Board.html for details.\n");
    
        /* Create application thread */
        pthread_attr_init(&attrs);
    
        detachState = PTHREAD_CREATE_DETACHED;
        /* Set priority and stack size attributes */
        retc = pthread_attr_setdetachstate(&attrs, detachState);
        if (retc != 0)
        {
            /* pthread_attr_setdetachstate() failed */
            while (1)
                ;
        }
    
        retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
        if (retc != 0)
        {
            /* pthread_attr_setstacksize() failed */
            while (1)
                ;
        }
    
        /* Create slave thread */
        priParam.sched_priority = 1;
        pthread_attr_setschedparam(&attrs, &priParam);
    
        retc = pthread_create(&thread0, &attrs, slaveThread, NULL);
        if (retc != 0)
        {
            /* pthread_create() failed */
            while (1)
                ;
        }
    
        return (NULL);
    }

    Apologies for the huge throwdown in code, but I hope this helps!

    Please let me know if you need more detail

    Thaanks

  • Hi

    Thank you for the detailed explanation.

    However, it is still not possible for me to figure out where the problem is as I do not have the F28379D you are communicating with.

    There are a few different ways you can try to solve this.

    First of all, you need to figure out where you code is failing. Is it SPI transfer that is failing, if yes, you should monitor the SPI bus to try to figure out what is going on.

    If it is the radio part that is failing, you should provide info on how it is failing (what is the status of the TX command)

    Since the CC1310 is the slave, it is the other device that is initiating the communication. Since I do not have this device available, you would need to implement a test code on a second CC1310 that ack as a master and that sends the same information as what the F28379D, so that I can run some tests here if I shall help you debug.

    I would assume that you would need to use callback mode and not blocking mode for your slave. If not, how are you handling that the master wants to communicate with the slave if it is busy with the radio?

    I recommend that you take one step back, and make sure that your SPI communication is OK. Use callback mode, and use a semaphore to indicate that you have read/written what you are supposed to. Do not do anything else than toggle a LED every time you have successfully communicated over SPI. Once this is up and running, you can implement RF communication.

    BR

    Siri

  • Hi Siri,

    Please don't leave me! I feel like I am so close to the solution now that I have found where the code seems to be kicking up a fuss!

    I stuck a whole bunch of tracking variables and found that the program seem to hang at this line without progressing further:

    RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);

    What it seems is happening is that SPI buffer is being read with no problems. This particular RF command seems to be the sticking point in this program.

    I've tried looking through what happens the SPI transaction variable and the Transaction seems to be completed, as is what it indicates when the rest of the programs is hung.

    It also seems as though whatever other board I try, there doesn't seem to be a change in result; the code still stops functioning at the same spot.

  • You need to move

    rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*) &RF_cmdPropRadioDivSetup, &rfParams);
            
    RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);

    outside the while(1) loop. This should only be done once (unless you actually do an RF_Close somewhere, and have to open the RF driver again, but I cannot see that you do this.

    BR

    Siri

  • Oh my god you are amazing!

    The code now moves on past the hang point and it seems to be continuously transmitting hooraaaay!

    Just to see if the code was actually transmitting something, I ran the packet rx example in Smart RF Studio with another CC1310 and whaddaya know! The right data really is being transmitted over RF! Yaaaay!

    Would I be doing a similar thing to what we just did, to get the vice versa set of functions going? (ie. where I need to use another cc1310 to receive this data from RF and send it over SPI)

    Thanks sooo much for your help!

  • Hi

    Glad to hear that you are making progress :-)

    To make the receiver, you can use the rfPacketRX example as a starting point. Please note that this example sets the repeat mode to 1, meaning that the device will never exit RX.

    You should replace the RF_runCmd with RF_postCmd for the RX command, and then pend on a semaphore (posted in the RX callback):

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

    /* Enter RX mode and stay forever in RX */
    RF_EventMask terminationReason = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, RF_EventRxEntryDone);

    while(1)
    {
        /* Waiting for packet */
        Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
        /* Writing packet to SPI*/
        // .

        // .
    }

    .

    .

    .


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

            RFQueue_nextEntry();

            /* Packet received */
            Semaphore_post(semHandle);

        }
    }

    BR

    Siri

  • Hi Siri,

    I'm so sorry this is ongoing, but which library would you be using to have semaphore_pend and post be compiled correctly? at the moment I get this issue:





    This is the code that I am currently using as well, having tried to place the appropriate Semaphore posts and pends in the right places. I haven't integrated the SPI arrangements yet as I thought I'd get the program to receive things over RF first, to which it only does one round and then stops.

    /*
     * Copyright (c) 2019, 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 *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    #include <semaphore.h>
    #include <BIOS.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "Board.h"
    
    /* Application Header files */
    #include "RFQueue.h"
    #include "smartrf_settings/smartrf_settings.h"
    
    /***** Defines *****/
    
    /* Packet RX Configuration */
    #define DATA_ENTRY_HEADER_SIZE 8  /* Constant header size of a Generic Data Entry */
    #define MAX_LENGTH             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) */
    
    sem_t semHandle;
    
    /***** Prototypes *****/
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    int potatotrack = 0;
    /* 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;
    static uint8_t packetLength;
    static uint8_t* packetDataPointer;
    
    
    static uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] =
    {
        Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    	PIN_TERMINATE
    };
    
    /***** Function definitions *****/
    
    void *mainThread(void *arg0)
    {
        sem_init(&semHandle, 0, 0);
        potatotrack = 1;
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        potatotrack = 2;
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        if (ledPinHandle == NULL)
        {
            while(1);
        }
    
        potatotrack = 3;
    
        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);
        }
    
        potatotrack = 4;
        /* Modify CMD_PROP_RX command for application needs */
        /* Set the Data Entity queue for received data */
        RF_cmdPropRx.pQueue = &dataQueue;
        /* Discard ignored packets from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
        /* Discard packets with CRC error from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
        RF_cmdPropRx.maxPktLen = MAX_LENGTH;
        RF_cmdPropRx.pktConf.bRepeatOk = 1;
        RF_cmdPropRx.pktConf.bRepeatNok = 1;
    
        potatotrack = 5;
        /* Request access to the radio */
    #if defined(DeviceFamily_CC26X0R2)
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioSetup, &rfParams);
    #else
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    #endif// DeviceFamily_CC26X0R2
    
        potatotrack = 6;
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        potatotrack = 61;
        /* Enter RX mode and stay forever in RX */
        RF_EventMask terminationReason = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx,
                                                   RF_PriorityNormal, &callback,
                                                   RF_EventRxEntryDone);
        potatotrack = 7;
    
    
        switch(terminationReason)
        {
            case RF_EventLastCmdDone:
                // A stand-alone radio operation command or the last radio
                // operation command in a chain finished.
                break;
            case RF_EventCmdCancelled:
                // Command cancelled before it was started; it can be caused
                // by RF_cancelCmd() or RF_flushCmd().
                break;
            case RF_EventCmdAborted:
                // Abrupt command termination caused by RF_cancelCmd() or
                // RF_flushCmd().
                break;
            case RF_EventCmdStopped:
                // Graceful command termination caused by RF_cancelCmd() or
                // RF_flushCmd().
                break;
            default:
                // Uncaught error event
                while(1);
        }
    
        potatotrack = 8;
    
        uint32_t cmdStatus = ((volatile RF_Op*)&RF_cmdPropRx)->status;
        switch(cmdStatus)
        {
            case PROP_DONE_OK:
                // Packet received with CRC OK
                potatotrack = 81;
                break;
            case PROP_DONE_RXERR:
                // Packet received with CRC error
                potatotrack = 82;
                break;
            case PROP_DONE_RXTIMEOUT:
                // Observed end trigger while in sync search
                potatotrack = 83;
                break;
            case PROP_DONE_BREAK:
                // Observed end trigger while receiving packet when the command is
                // configured with endType set to 1
                potatotrack = 84;
                break;
            case PROP_DONE_ENDED:
                // Received packet after having observed the end trigger; if the
                // command is configured with endType set to 0, the end trigger
                // will not terminate an ongoing reception
                potatotrack = 85;
                break;
            case PROP_DONE_STOPPED:
                // received CMD_STOP after command started and, if sync found,
                // packet is received
                potatotrack = 86;
                break;
            case PROP_DONE_ABORT:
                // Received CMD_ABORT after command started
                potatotrack = 87;
                break;
            case PROP_ERROR_RXBUF:
                // No RX buffer large enough for the received data available at
                // the start of a packet
                potatotrack = 88;
                break;
            case PROP_ERROR_RXFULL:
                // Out of RX buffer space during reception in a partial read
                potatotrack = 89;
                break;
            case PROP_ERROR_PAR:
                // Observed illegal parameter
                potatotrack = 810;
                break;
            case PROP_ERROR_NO_SETUP:
                // Command sent without setting up the radio in a supported
                // mode using CMD_PROP_RADIO_SETUP or CMD_RADIO_SETUP
                potatotrack = 811;
                break;
            case PROP_ERROR_NO_FS:
                // Command sent without the synthesizer being programmed
                potatotrack = 812;
                break;
            case PROP_ERROR_RXOVF:
                // RX overflow observed during operation
                potatotrack = 813;
                break;
            default:
                // Uncaught error event - these could come from the
                // pool of states defined in rf_mailbox.h
                potatotrack = 814;
                while(1);
        }
    
        potatotrack = 9;
    
        while(1){
    
            Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
    
        }
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        potatotrack = 91;
        if (e & RF_EventRxEntryDone)
        {
            potatotrack = 10;
            /* Toggle pin to indicate RX */
            PIN_setOutputValue(ledPinHandle, Board_PIN_LED2,
                               !PIN_getOutputValue(Board_PIN_LED2));
            potatotrack = 11;
            /* Get current unhandled data entry */
            currentDataEntry = RFQueue_getDataEntry();
            potatotrack = 12;
            /* 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);
    
            potatotrack = 13;
            /* Copy the payload + the status byte to the packet variable */
            memcpy(packet, packetDataPointer, (packetLength + 1));
            potatotrack = 14;
            RFQueue_nextEntry();
            potatotrack = 15;
            Semaphore_post(semHandle);
        }
    }
    

    Thanks a million!

    You're an absolute lifeesaver!

  • Hi

    Please use the rfWakeOnRadioTX as an example on how to use a semaphore.

    BR

    Siri