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.

CC2640R2F: spi transfer 24 bits data

Part Number: CC2640R2F
Other Parts Discussed in Thread: DAC60508

Hi, I am trying to transmit 24bit data. Since the data size is bigger than 16bit, I am trying to split it into 8bit and send them seperately.

Like, if transmit data is 010203, then it is transmitted 01,02,03. 

I am worried if the data is overwritten or dropped and also I am sure that I set spiTransaction.count parameter right.

But I have a trouble in sending data. my code is attached below, so could you check if my code is right?

typedef union Txdata{
uint32_t DAC;
uint8_t transbuffer[4];

}Txdata;

SPI_Handle spiHandle;
SPI_Params spiParams;
SPI_Transaction spiTransaction;
Txdata txdata;
uint32_t transmitBuf;
bool TransOK;

/* Call driver init functions */
SPI_init();
/*initialize SPI parameters*/
SPI_Params_init(&spiParams);
spiParams.dataSize=8;//8-bit data size

spiHandle=SPI_open(Board_SPI_DAC,&spiParams);

if (spiHandle == NULL) {
/* SPI_open() failed */
while (1);
}

//Fill in transmitBuffer
spiTransaction.count=3;
transmitBuf=0x010888;//010FFF;
txdata.DAC=transmitBuf;

int i;
while(1)
{
TransOK=1;
for(i=0;i<3;i++)
{
spiTransaction.txBuf=txdata.transbuffer+i;
TransOK = SPI_transfer(spiHandle,&spiTransaction);
if (!TransOK) {
// Error in SPI or transfer already in progress
}
}

}

  • Please look at the driver documentation in the SDK. There you will find different code examples.

    A way to transmit 3 bytes, one byte at a time, is shown below:

    SPI_Handle handle;
    SPI_Params params;
    SPI_Transaction transaction;
    uint8_t txBuf[] = {0x01, 0x02, 0x03}; // Transmit buffer
    
    // Init SPI and specify non-default parameters
    SPI_Params_init(&params);
    params.bitRate     = 1000000;
    params.frameFormat = SPI_POL1_PHA1;
    params.mode        = SPI_MASTER;
    
    // Configure the transaction
    transaction.count = sizeof(txBuf);
    transaction.txBuf = txBuf;
    transaction.rxBuf = NULL;
    
    // Open the SPI and perform the transfer
    handle = SPI_open(Board_SPI, &params);
    SPI_transfer(handle, &transaction);

    Siri

  • Thank you for your answer. I tried to access the link but it is blocked. And what it bitrate?
    And if I set like that, I don't need to be worried about data overwritten?
  • I have now fixed the link. Not sure why you think that anything should be overwritten? Have you seen anything like this when running the example? The bit rate is set in the code snippet I sent:

    params.bitRate = 1000000; // SPI bit rate in Hz

    Siri
  • I checked the data through oscilloscope and it is different from what I set. I don't know what's the problem so I guess it is overwritten.
  • I wonder how this spi works. cs would be low util all the data is transmitted? or Do I need to transmit all before cs gets high.
    Is there any parameter that I can edit cs duration?
  • I have implemented the code for you in an example so that you can test yourself. I used the 1.50 SDK for the CC2640R2 and used the empty example as a starting point.

    I modified CC2640R2_LAUNCXL.h to use the following DIOs for SPI1:

    #define CC2640R2_LAUNCHXL_SPI1_MISO IOID_21
    #define CC2640R2_LAUNCHXL_SPI1_MOSI IOID_15
    #define CC2640R2_LAUNCHXL_SPI1_CLK  IOID_0
    #define CC2640R2_LAUNCHXL_SPI1_CSN  IOID_12

    The modified empty.c is shown below:

    /*
     *  ======== empty.c ========
     */
    
    /* For usleep() */
    #include <unistd.h>
    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
     #include <ti/drivers/SPI.h>
    
    /* Board Header file */
    #include "Board.h"
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        /* 100 second delay */
        uint32_t time = 100;
    
        /* Call driver init functions */
        SPI_init();
    
        SPI_Handle handle;
        SPI_Params params;
        SPI_Transaction transaction;
        uint8_t txBuf[] = {0x01, 0x02, 0x03}; // Transmit buffer
    
        // Init SPI and specify non-default parameters
        SPI_Params_init(&params);
        params.bitRate     = 1000000;
        params.frameFormat = SPI_POL1_PHA1;
        params.mode        = SPI_MASTER;
    
        // Configure the transaction
        transaction.count = sizeof(txBuf);
        transaction.txBuf = txBuf;
        transaction.rxBuf = NULL;
    
        // Open the SPI and perform the transfer
        handle = SPI_open(CC2640R2_LAUNCHXL_SPI1, &params);
    
        while (1)
        {
            usleep(time);
            SPI_transfer(handle, &transaction);
        }
    }

    This code will have the 3 bytes being send over and over again. Chip select will be asserted for every byte. If you want to change this I think you will need to control the CSn manually from the application instead of letting the driver take care of this.

    Siri

  • Thank you very much for your help.

    Now I can use spi well thanks to your help.

    I am working on communication with DAC chip which is DAC60508 from TI.

    I checked all the signals worked well as I set but the chip did not work.

    I sent 0x0a0fff to make out2 full voltage but it is almost 0V.

    So I wonder I write register in DAC right and checked rx from there.

    I got rxbuf like below. I sent 0x0a0fff but received 0x0a0bff. The other part of code is the same as yours except transaction.mode. I set it SPI_POL0_PHA1.

    Do you think this is the problem?

  • I suggest that you post a new question regarding the DAC60508 in the following forum:

    BR

    Siri

  • Thanks for your help, I asked DAC forum and got feedback that DAC is not working because /cs is high every 8bits.

    I want to use gpio to make /cs low for 24 bit but I am not sure how to do  it.

    Since I don't know how SPI_transfer function works, I have no idea how to make /cs is low between every bits.

    For your understanding, I attached the photo. yellow one is /cs.

  • You can control the CSn manually through the Pin Driver:

    #define CC2640R2_LAUNCHXL_SPI1_MISO             IOID_21
    #define CC2640R2_LAUNCHXL_SPI1_MOSI             IOID_15
    #define CC2640R2_LAUNCHXL_SPI1_CLK              IOID_0
    #define CC2640R2_LAUNCHXL_SPI1_CSN              PIN_UNASSIGNED

    /*
     *  ======== empty.c ========
     */
    
    /* For usleep() */
    #include <unistd.h>
    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
    #include <ti/drivers/SPI.h>
    #include <ti/drivers/PIN.h>
    
    /* Board Header file */
    #include "Board.h"
    
    /* Pin driver handle */
    static PIN_Handle csnPinHandle;
    static PIN_State csnPinState;
    
    PIN_Config pinTable[] =
    {
        IOID_12 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        /* Open csn pin */
        csnPinHandle = PIN_open(&csnPinState, pinTable);
        if (csnPinHandle == NULL)
        {
            while(1);
        }
    
        /* 100 second delay */
        uint32_t time = 100;
    
        /* Call driver init functions */
        SPI_init();
    
        SPI_Handle handle;
        SPI_Params params;
        SPI_Transaction transaction;
        uint8_t txBuf[] = {0x01, 0x02, 0x03}; // Transmit buffer
    
        // Init SPI and specify non-default parameters
        SPI_Params_init(&params);
        params.bitRate     = 1000000;
        params.frameFormat = SPI_POL1_PHA1;
        params.mode        = SPI_MASTER;
    
        // Configure the transaction
        transaction.count = sizeof(txBuf);
        transaction.txBuf = txBuf;
        transaction.rxBuf = NULL;
    
        // Open the SPI and perform the transfer
        handle = SPI_open(CC2640R2_LAUNCHXL_SPI1, &params);
    
        while (1)
        {
            usleep(time);
            PIN_setOutputValue(csnPinHandle, IOID_12, 0); // Set CSn low
            SPI_transfer(handle, &transaction);
            PIN_setOutputValue(csnPinHandle, IOID_12, 1); // Set CSn high
        }
    }

    BR

    Siri

  • Is there any reason for usleep?
    Because I have an error that "unresolved symbol usleep" so I can't use that;
  • The usleep was just to insert a delay between the transactions. You can either remove it or add: #include <unistd.h>

    I just realized also that you do not have to control the CSn manually to have all 3 bytes sent without having CSn being pulled high in-between bytes. You can simply change minDmaTransferSize from 10 to 1 as shown below:

    {
            .baseAddr           = SSI1_BASE,
            .intNum             = INT_SSI1_COMB,
            .intPriority        = ~0,
            .swiPriority        = 0,
            .powerMngrId        = PowerCC26XX_PERIPH_SSI1,
            .defaultTxBufValue  = 0,
            .rxChannelBitMask   = 1<<UDMA_CHAN_SSI1_RX,
            .txChannelBitMask   = 1<<UDMA_CHAN_SSI1_TX,
            .mosiPin            = CC2640R2_LAUNCHXL_SPI1_MOSI,
            .misoPin            = CC2640R2_LAUNCHXL_SPI1_MISO,
            .clkPin             = CC2640R2_LAUNCHXL_SPI1_CLK,
            .csnPin             = CC2640R2_LAUNCHXL_SPI1_CSN,
            .minDmaTransferSize = 1
        }
    };

    Siri

  • If minDmaTransferSize is set as 1, then 3bytes would be sent in onetime?
    Does this work like spi send 1 bit at a time?
  • When minDmaTransferSize = 1, all bytes will be sent using DMA, and CSn will NOT be pulled high between bytes. Please try it and monitor the SPI lines and you will see how it works.

    Siri
  • I tried it and it works well. I just wondered what that parameter means. Thank you for all your kind answers.