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/SIMPLELINK-CC2640R2-SDK: SPI transfer problem when two spi handle share same bus

Part Number: SIMPLELINK-CC2640R2-SDK
Other Parts Discussed in Thread: CC2640R2F

Tool/software: TI-RTOS

Hi everyone,

I am living a trouble with SPI driver and my sdk version 1_35.
There is one master (CC2640R2F) and two slaves in my system. These two slaves shares the same SCLK,MOSI,MISO. One slave uses POL0_PHA1 and other uses POL1_PHA1 spi frame format.

typedef enum CC2640R2_LAUNCHXL_SPIName {
    CC2640R2_LAUNCHXL_SPI0 = 0,
    CC2640R2_LAUNCHXL_SPI1,

    CC2640R2_LAUNCHXL_SPICOUNT
} CC2640R2_LAUNCHXL_SPIName;

typedef enum CC2640R2_LAUNCHXL_SPIName {
    CC2640R2_LAUNCHXL_SPI0 = 0,
    CC2640R2_LAUNCHXL_SPI1,

    CC2640R2_LAUNCHXL_SPICOUNT
} CC2640R2_LAUNCHXL_SPIName;


const SPICC26XXDMA_HWAttrsV1 spiCC26XXDMAHWAttrs[CC2640R2_LAUNCHXL_SPICOUNT] = {
    {
        .baseAddr           = SSI0_BASE,
        .intNum             = INT_SSI0_COMB,
        .intPriority        = ~0,
        .swiPriority        = 0,
        .powerMngrId        = PowerCC26XX_PERIPH_SSI0,
        .defaultTxBufValue  = 0,
        .rxChannelBitMask   = 1<<UDMA_CHAN_SSI0_RX,
        .txChannelBitMask   = 1<<UDMA_CHAN_SSI0_TX,
        .mosiPin            = CC2640R2_LAUNCHXL_SPI0_MOSI,
        .misoPin            = CC2640R2_LAUNCHXL_SPI0_MISO,
        .clkPin             = CC2640R2_LAUNCHXL_SPI0_CLK,
        .csnPin             = CC2640R2_LAUNCHXL_SPI0_CSN,
        .minDmaTransferSize = 10
    },
    {
        .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 = 10
    }
};

const SPI_Config SPI_config[CC2640R2_LAUNCHXL_SPICOUNT] = {
    {
         .fxnTablePtr = &SPICC26XXDMA_fxnTable,
         .object      = &spiCC26XXDMAObjects[CC2640R2_LAUNCHXL_SPI0],
         .hwAttrs     = &spiCC26XXDMAHWAttrs[CC2640R2_LAUNCHXL_SPI0]
    },
    {
         .fxnTablePtr = &SPICC26XXDMA_fxnTable,
         .object      = &spiCC26XXDMAObjects[CC2640R2_LAUNCHXL_SPI1],
         .hwAttrs     = &spiCC26XXDMAHWAttrs[CC2640R2_LAUNCHXL_SPI1]
    },
};

const uint_least8_t SPI_count = CC2640R2_LAUNCHXL_SPICOUNT;

I am using CC2640R2_LAUNCHXL_SPI0 for slave which uses POL0_PHA1 and CC2640R2_LAUNCHXL_SPI1 for slave which uses POL1_PHA1.

I opened SPI interface by calling;

handle0 = SPI_open(CC2640R2_LAUNCHXL_SPI0,&params0)
handle1 = SPI_open(CC2640R2_LAUNCHXL_SPI1,&params1)

I checked both spi handle,  these are not equal to NULL.

When i try to write or read something by SPI, the program seems to be stuck in SPI_transfer function. I did not get SPI_Status value because, SPI_transfer never return.

Everything works when only one slave is connected to SPI (I mean that, i did one spi_open for one slave and other slave is deasserted)
I only drive one spi slave at one time.


I am wondering that Does the issue occurs because of two different spi handle shares the same spi bus?
Is it permitted that two spi handle use the same SPI bus ?
Do you have any suggestion that why this problem occurs ?
Is there any way to change spi frame format without reopening the spi interface ?

Thanks for your attention.
Have a nice day

  • Hi Erdem,

    Do I understand you correctly that you are using both SPI0 and SPI1 (different output pins as specified in your board file) connected together to both slaves (In other words, both the slaves are connected to both SPI0 and SPI1)?

    In this case I would expect some problem if both SPI0 and SPI1 are connected to the same bus as the two different frame formats have different clock states (polarity).
  • Hi,

    Sorry for misunderstanding, i hope that, this explanation helps you.

    For example;

    #define CC2640R2_LAUNCHXL_SPI0_MOSI IOID_10
    #define CC2640R2_LAUNCHXL_SPI0_MISO IOID_11
    #define CC2640R2_LAUNCHXL_SPI0_CLK IOID_12
    #define CC2640R2_LAUNCHXL_SPI0_CSN PIN_UNASSIGNED

    #define CC2640R2_LAUNCHXL_SPI1_MOSI IOID_10
    #define CC2640R2_LAUNCHXL_SPI1_MISO IOID_11
    #define CC2640R2_LAUNCHXL_SPI1_CLK IOID_12
    #define CC2640R2_LAUNCHXL_SPI1_CSN PIN_UNASSIGNED

    I uses both SPI0 and SPI1 to control two different SPI slaves. These SPI slaves shares same bus and only one of them works at a time.
    My problem is that these two SPI slaves use different polarity and phase format. Because of that, i use SPI0 and SPI1 to overcome this problem. However, when i try to attempt sending data via SPI, SPI_transfer function is stuck.

    I have an alternative solution; i am not sure that this is a safe way.
    Before sending data to slave, to set frame format
    HWREG(SSI0_BASE + SSI_O_CR0) = something ;

    Then, send data by using SPI_transfer.

    Is it safe method ?

    Thanks for your quick response
  • Hi,

    I'm surprised that you are able to open both SPI0 and SPI1, are you sure that both of them return null handles?
    You should not be able to assign the same output pin to both of them, the second one should return with a null handle as the pins are already allocated by the first SPI_open.

    This is indeed a pickle, I assume you have no way of separating the two SPI slaves so they have a separate bus each)?

    Theoretically, you could try to bypass it all with a solution like the one you proposed. The requirement is that the SSI module is disabled while being configure, which it is between transfers (gets enabled during SPI_transfer and disabled when the transfer completes). However, I don't know what behavior you could expect from the SPI driver if you do it this way.
  • Hi,

    Is it possible to change polarity and phase by using SPI_control() function ?

    Edit
    ------
    It is not possible to change polarity and phase via spi commands.
    These commands only support partial return, csn pin and csn wakeup pins


    Thanks

  • Hi,

    It is not possible to change this using SPI_control I'm afraid.