This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/LAUNCHXL-CC1352R1: CC1352 BLE and SPI communication with AS8510 IC.

Part Number: LAUNCHXL-CC1352R1
Other Parts Discussed in Thread: MSP430FR5969

Tool/software: TI-RTOS

Hello all,

i worked on MSP430FR5969 with AS8510 IC(SPI Communication), and i am getting results.
Same things i would like to implement with CC1352 BLE coding, so i refered the SPI master program for programming with BLE coding. its not at all showing anything. actually in receiveBuffer i am getting 0xFF result in all time.

Is anyone implemented the coding for another slave on SPI communication than internally defined SPI communication.

Cheers,

Anil D. 

  • It's not clear from your post if this is a SPI or SPI combined with BLE issue.

    - Have you tried dev.ti.com/.../node and cehcked if you manage to read out the data you are interested in?
    - If this example doesn't work, compare the SPI bus when you are using a MSP and when you are using CC1352 to see what is different.
  • Ter,

    I got all results with MSP430fr5969 with Slave IC AS8510. Now i tried with cc1352 BLE code integrated with SPI communication code, Not getting results. So now trying with SPIMaster code which is given in SDK.
    whichever link you shared that only i followed, did not get the results.
    my main goal to read the data(current and voltage) from the Slave IC.

    Cheers,
    Anil D.
  • TER,

    Checking the coding with SPIMaster code, program is going to stuck in "sem_wait(&masterSem);" it means that slave is not pulling the Board_SPI_SLAVE_READY pin LOW. i didn't get this condition. So that i removed that semaphore waiting for the slave to make that line low. But now also i am not getting results.

    I did that configuration according to the Pin configuration given in Board_initGeneral(); function, like SPI MOSI,MISO,CS,INT pin. But there also i have doubt that how they make that SPI MOSI pin as a input pin. Actually it should be output pin, but in config there is not such provision to make it output, its saying make it GPIO output pin, but i don't want that. what to do?

    Anil D.
  • Again, what is the difference between the MSP and CC1312? I assume that the slave should have pulled the line low in both cases?

    Have you monitored the SPI lines in the two cases to see what the difference is?
  • I think you are talking about I2C communication. as i know there is no concept of pull the line low in spi communication.

    I2C link : www.circuitbasics.com/.../
    i studied this link here they mentioned that which slave address matched with slave that slave will pull the SDA line low.
    i am not getting your point that, why line will be pulled by slave device?
  • You wrote "Checking the coding with SPIMaster code, program is going to stuck in "sem_wait(&masterSem);" it means that slave is not pulling the Board_SPI_SLAVE_READY pin LOW." Hence the SPI pulled low question.

    I still waiting for a plot that compares working and not working SPI communication.
  • Sample code only designed like that, i too don't know why its like that. They used 2 pins to insure the SPI communication between master and slave device. they are making that pin low - high and ensuring the spi communication.
    so there in that only i got that problem.

    both thing i can't compare here, because basic program with cc1352 need to give me at-least some results then only i can do something.
    but here i am not getting anything. but still with logical analyser i will check and update you.
  • SPI is a 4 line interface, which 2 pins are you using?
  • /*
     * Copyright (c) 2018, 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.
     */
    
    /*
     *  ======== spimaster.c ========
     */
    #include <stdbool.h>
    #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  (30)
    #define MASTER_MSG      ("Hello from master, msg#: ")
    
    #define MAX_LOOP        (10)
    
    static Display_Handle display;
    
    unsigned char masterRxBuffer[SPI_MSG_LENGTH];
    unsigned char masterTxBuffer[SPI_MSG_LENGTH];
    
    /* Semaphore to block master until slave is ready for transfer */
    sem_t masterSem;
    
    /*
     *  ======== slaveReadyFxn ========
     *  Callback function for the GPIO interrupt on Board_SPI_SLAVE_READY.
     */
    void slaveReadyFxn(uint_least8_t index)
    {
        sem_post(&masterSem);
    }
    
    /*
     *  ======== masterThread ========
     *  Master SPI sends a message to slave while simultaneously receiving a
     *  message from the slave.
     */
    void *masterThread(void *arg0)
    {
        SPI_Handle      masterSpi;
        SPI_Params      spiParams;
        SPI_Transaction transaction;
        uint32_t        i;
        bool            transferOK;
        int32_t         status;
    
        /*
         * 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:
         *
         * spimaster example:
         *     * Board_SPI_MASTER_READY is configured as an output pin.  During the
         *       'handshake' this pin is changed from low to high output.  This
         *       notifies the slave the master is ready to run the application.
         *       Afterwards, the pin is used by the master to notify the slave it
         *       has opened Board_SPI_MASTER.  When Board_SPI_MASTER is opened, this
         *       pin will be pulled low.
         *
         *     * Board_SPI_SLAVE_READY is configured as an input pin. During the
         *       'handshake' this pin is read & a high value will indicate the slave
         *       ready to run the application.  Afterwards, a falling edge interrupt
         *       will be configured on this pin.  When the slave is ready to perform
         *       a transfer, it will pull this pin low.
         *
         * Below we set Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY initial
         * conditions for the 'handshake'.
         */
        GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_INPUT);
    
        /*
         * Handshake - Set Board_SPI_MASTER_READY high to indicate master is ready
         * to run.  Wait Board_SPI_SLAVE_READY to be high.
         */
        GPIO_write(Board_SPI_MASTER_READY, 1);
        while (GPIO_read(Board_SPI_SLAVE_READY) == 0) {}
    
        /* Handshake complete; now configure interrupt on Board_SPI_SLAVE_READY */
        GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
        GPIO_setCallback(Board_SPI_SLAVE_READY, slaveReadyFxn);
        GPIO_enableInt(Board_SPI_SLAVE_READY);
    
        /*
         * Create synchronization semaphore; the master will wait on this semaphore
         * until the slave is ready.
         */
        status = sem_init(&masterSem, 0, 0);
        if (status != 0) {
            Display_printf(display, 0, 0, "Error creating masterSem\n");
    
            while(1);
        }
    
        spiParams.frameFormat = SPI_POL1_PHA0;
        spiParams.dataSize = 8;       // 8-bit data size
        spiParams.bitRate = 8000000;
        spiParams.mode = SPI_MASTER;
        spiParams.transferMode = SPI_MODE_BLOCKING;
        spiParams.transferTimeout = SPI_WAIT_FOREVER;
    
        /* Open SPI as master (default) */
        SPI_Params_init(&spiParams);
    
        masterSpi = SPI_open(Board_SPI_MASTER, &spiParams);
        if (masterSpi == NULL) {
            Display_printf(display, 0, 0, "Error initializing master SPI\n");
            while (1);
        }
        else {
            Display_printf(display, 0, 0, "Master SPI initialized\n");
        }
    
        /*
         * Master has opened Board_SPI_MASTER; set Board_SPI_MASTER_READY high to
         * inform the slave.
         */
        GPIO_write(Board_SPI_MASTER_READY, 0);
    
        /* Copy message to transmit buffer */
        strncpy((char *) masterTxBuffer, MASTER_MSG, SPI_MSG_LENGTH);
    
        for (i = 0; i < MAX_LOOP; i++) {
            /*
             * Wait until slave is ready for transfer; slave will pull
             * Board_SPI_SLAVE_READY low.
             */
    //        sem_wait(&masterSem);
    
            /* Initialize master SPI transaction structure */
            masterTxBuffer[sizeof(MASTER_MSG) - 1] = (i % 10) + '0';
            memset((void *) masterRxBuffer, 0, SPI_MSG_LENGTH);
            transaction.count = SPI_MSG_LENGTH;
            transaction.txBuf = (void *) masterTxBuffer;
            transaction.rxBuf = (void *) masterRxBuffer;
    
            /* Toggle user LED, indicating a SPI transfer is in progress */
            GPIO_toggle(Board_GPIO_LED1);
    
            /* Perform SPI transfer */
            transferOK = SPI_transfer(masterSpi, &transaction);
            if (transferOK) {
                Display_printf(display, 0, 0, "Master received: %s", masterRxBuffer);
            }
            else {
                Display_printf(display, 0, 0, "Unsuccessful master SPI transfer");
            }
    
            /* Sleep for a bit before starting the next SPI transfer  */
            sleep(3);
        }
    
        SPI_close(masterSpi);
    
        /* Example complete - set pins to a known state */
        GPIO_disableInt(Board_SPI_SLAVE_READY);
        GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        GPIO_write(Board_SPI_MASTER_READY, 0);
    
        Display_printf(display, 0, 0, "\nDone");
    
        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 master 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 threads */
        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 master thread */
        priParam.sched_priority = 1;
        pthread_attr_setschedparam(&attrs, &priParam);
    
        retc = pthread_create(&thread0, &attrs, masterThread, NULL);
        if (retc != 0) {
            /* pthread_create() failed */
            while (1);
        }
    
        return (NULL);
    }
    

    see the uploaded file, they also didn't mentioned gpio pins , but they simply used in the program for semaphore. for what they used it mentioned there.

    yes spi is 4 wire protocol. but sample code itself have other 2 wires. what can i do?

    spimaster_CC1352R1_LAUNCHXL_tirtos_ccs.rar

    see this is the whole project with i amtrying to implement SPI communication.

  • Sorry for the confusion, I forgot the extra handshake in the example. As you see from the readme 2 extra DIOs are used to do an handshake to sync master and slave. For your test you don't want this handshake and hence you need to remove the handshake parts from the code.
  • Okay i will remove that handshake program(semaphore).  but for my curiosity i want to know that where i can use this semaphore concept - handshaking.

    7142.simple_peripheral.c

    see in this file i implemented how you said. just look "static void SimplePeripheral_init(void)" this function. can you please confirm once. i will also try by my side. this is the code of peripheral which is main thread i created for the implementation.

     

  • Handshake require that both master and slave has this implemented. In your case you are communicating with a sensor that uses SPI and then you have to use the protocol described in the sensor datasheet.