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.

CCS/CC2650: Reading SPI

Part Number: CC2650
Other Parts Discussed in Thread: ADS8881,

Tool/software: Code Composer Studio

Hi, I want to read the ADC ADS8881 of 18-bit with the CC2650 via SP.

Im stuck with the SPI code and the ADC is 18-bits, the CC2650 just can read frames of 16-bit. How can I do a two part reading?

  • Hi Eduardo,

    I would suggest you try to set the dataSize to 9-bits and let the SPI driver handle the 18-bit data as two frames.
    To try this out and see if it works, set dataSize to 9 and then try to read two entries from the ADC (each entry would be 9 bits). You would then have to recreate the 18-bit value by combining the two frames.
  • Hi, thaks for responding

    Im using this code but I don't see changes on the rxbuf

    *  ======== empty.c ========
     */
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/SPI.h>
    #include <ti/drivers/spi/SPICC26XXDMA.h>
    
    /* Board Header files */
    #include "Board.h"
    
    #define delay_ms(i)     Task_sleep( ((i) * 1000) / Clock_tickPeriod )
    #define TASKSTACKSIZE   516
    
    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];
    
    static SPI_Handle spiHandle = NULL;
    static SPI_Params spiParams;
    SPI_Transaction spiTransaction;
    
    
    static PIN_Handle hFlashPin = NULL;
    static PIN_State flashPinState;
    static PIN_Config BoardFlashPinTable[] =
    {
        Board_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN, // Ext. flash chip select
        PIN_TERMINATE
    };
    
    
    
    Void taskFxn(UArg arg0, UArg arg1)
    {
        System_printf("Start SPI task\n");
    
        SPI_Params_init(&spiParams);
        spiParams.dataSize     = 9;
        spiParams.transferMode = SPI_MODE_BLOCKING;
        spiParams.mode = SPI_MASTER;
        spiParams.bitRate = 100000;
        spiHandle = SPI_open(Board_SPI0, &spiParams);
    
        while (1) {
            //delay_ns(2);
            //const uint8_t wbuf[] = {0x90, 0xFF, 0xFF, 0x00};
            uint16_t rbuf[2];
    
            int ret = 0;
    
            SPI_Transaction masterTransaction;
            masterTransaction.count  = 9;
            masterTransaction.txBuf  = 0x000000001;
            masterTransaction.arg    = NULL;
            masterTransaction.rxBuf  = NULL;
            ret = SPI_transfer(spiHandle, &masterTransaction) ? 0 : -1;
            System_printf("Returned %d\n",ret);
    
            //delay_ns(600);
    
            masterTransaction.count  = 9;
            masterTransaction.txBuf  = NULL;
            masterTransaction.arg    = NULL;
            masterTransaction.rxBuf  = rbuf;
    
            ret = SPI_transfer(spiHandle, &masterTransaction) ? 0 : -1;
            System_printf("Returned %d\n",ret);
    
        }
    }
    
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        Task_Params taskParams;
    
        /* Call board init functions */
        Board_initGeneral();
        Board_initSPI();
    
        /* Construct Task  thread */
        Task_Params_init(&taskParams);
        taskParams.stackSize = TASKSTACKSIZE;
        taskParams.stack = task0Stack;
        Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL);
    
        hFlashPin = PIN_open(&flashPinState, BoardFlashPinTable);
        if (!hFlashPin) {
            System_abort("Error initializing flash pin\n");
        }
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    




    I'm not sure what I'm doing wrong

  • Hi Eduardo,

    Some observations on the code snippet you provided:

    masterTransaction.txBuf  = 0x000000001;

    The txBuf and rxBuf arguments of the transaction struct are pointers to the data, setting txBuf as you will cause the SPI to send 
    data starting from the memory location 0x00000001 (if not causing a crash to start with).

    You also set the transaction count to 9 each time, this implies you want to send/receive 9 entries. This means the buffers provided need to be sized accordingly. For example, the rbuf would need to be at least 9 entries deep in your case unless you change the count to 2 (I guess you actually intend to read only 2 entries).

     

  • Part Number: CC2650

    Tool/software: Code Composer Studio

    Hi, Im trying to read an ADS8881 of 18 bits, i have this code but I dont know how to read the 18 bit

    uint16_t wbuf[] = {(uint16_t) 0b1};
    uint16_t rbuf[2];
    int ret = 0;

    Void taskFxn(UArg arg0, UArg arg1)
    {
        System_printf("Start SPI task\n");
    
        SPI_Params_init(&spiParams);
        spiParams.dataSize = 9;
        //spiParams.transferMode = SPI_MODE_BLOCKING;
        spiParams.mode = SPI_MASTER;
        spiParams.bitRate = 10000000;
        spiParams.frameFormat = SPI_TI;
        spiHandle = SPI_open(Board_SPI0, &spiParams);
        if (spiHandle == NULL)
        {
            while (1);
            System_printf("Start SPI failed"); // SPI_open() failed
        }
    
        while (1)
        {
    
            delay_ms(100);
            SPI_Transaction masterTransaction;
            masterTransaction.count = 18;
            masterTransaction.txBuf = wbuf;
            masterTransaction.rxBuf = rbuf;
            ret = SPI_transfer(spiHandle, &masterTransaction);
        }

    This is other try:

     while (1)
        {
    
            delay_ms(1000);
            SPI_Transaction masterTransaction;
            masterTransaction.count = 1;
            masterTransaction.txBuf = wbuf;
            masterTransaction.rxBuf = rbuf;
            ret = SPI_transfer(spiHandle, &masterTransaction);
    
            delay_ms(0.7);
    
    
            masterTransaction.count = 2;
            masterTransaction.txBuf = NULL;
            masterTransaction.rxBuf = rbuf;
            ret = SPI_transfer(spiHandle, &masterTransaction);
    
        }

    I will appreciate any code as an example to read the 18 bits

  • Hi Eduardo,

    I will merge this into your existing thread as it is basically your initial problem. Keeping to one thread makes it easier to support and for others to find possible answers in the future when searching the forums.
  • Hi,

    I would use the SPI_POL0_PHA0 frame format instead of the TI one, it seems to match your device better from what I can tell. You should also lower the  bit-rate from 10 MHz to 4 MHz which is the verified maximum that is supported by the device.

    With these changes, I would simply setup a transfer like this:

    uint16_t wbuf[2] = {0};
    uint16_t rbuf[2] = {0};
    
    masterTransaction.count = 2;
    masterTransaction.txBuf = wbuf;
    masterTransaction.rxBuf = rbuf;
    ret = SPI_transfer(spiHandle, &masterTransaction);

    If you do not need to write anything to the device at all you could set txBuf to NULL.

    You would also need to change the minDmaTransfer size in your board file to avoid the driver using polling mode:

    const SPICC26XXDMA_HWAttrsV1 spiCC26XXDMAHWAttrs[CC1310_LAUNCHXL_SPICOUNT] = {
        {
            .baseAddr           = SSI0_BASE,
            .intNum             = INT_SSI0_COMB,
            .intPriority        = ~0,
            .swiPriority        = 0,
            .powerMngrId        = PowerCC26XX_PERIPH_SSI0,
            .defaultTxBufValue  = 0xFF,
            .rxChannelBitMask   = 1<<UDMA_CHAN_SSI0_RX,
            .txChannelBitMask   = 1<<UDMA_CHAN_SSI0_TX,
            .mosiPin            = CC1310_LAUNCHXL_SPI0_MOSI,
            .misoPin            = CC1310_LAUNCHXL_SPI0_MISO,
            .clkPin             = CC1310_LAUNCHXL_SPI0_CLK,
            .csnPin             = CC1310_LAUNCHXL_SPI0_CSN,
            .minDmaTransferSize = 1 // <---- THIS ONE NEED TO BE SET TO 1 TO AVOID POLLING MODE
    }

  • Hi, in my board file is this constant

    const SPICC26XXDMA_HWAttrsV1 spiCC26XXDMAHWAttrs[CC2650_LAUNCHXL_SPICOUNT]

    but it doesen't have the .minDmaTransferSize field, and when I try to add doesn't compile
  • I'm using this configuration:

    Where have  I to take in count the time requirements of the convertion? And How should I proceed?

  • Hi,

    Ah my bad, the SPI driver shipped with the CC2650 BLE SDK is a bit older and do not contain the SPI Polling mode. You should be good without this in the HWAttrs.

    I would say to have to take the time requirements into account on application level, it is nothing you can do to the SPI driver itself.
  • Hello, I noticed that MSBs are saved in the second reading, ie rbuf [1,3,5 ....] and LSBs in the first reading with rbuf [0,2,4, .....]

    But a bit is being lost between the MSBs and the LSBs since the maximum number obtained is 255, which is equivalent to 1111 1111, when it should be 511 or 1 111 1111, numbers that are presented in the LSB.

    What would you recommend? I was thinking about doing a reading of 16 and giving up the remaining LSBs but I do not know how to do it

  • Hi,

    Based on the picture above, I would say the MSB would be found in the first element of the rbuf.
    Keep in mind that the data you receive should be right-aligned, which means you should find bit 17-9 in the lower part of rbuf[0] and bit 8-0 in the lower part of rbuf[1].

    For example, I would expect to set the value together something like this:

    uint32_t value = ((rbuf[0] & 0x01FF) << 9) | (rbuf[1] & 0x01FF);

    Have you scoped the signals to see what data you receive and compared that to your buffer value?