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: SPI communication between CC1310 and LPS22HB sensor - No clock present

Part Number: LAUNCHXL-CC1310
Other Parts Discussed in Thread: CC1310

Greetings

I am attempting to write functions to condense SPI communication between a CC1310 and a LPS22HB pressure sensor. Instead of continuously initialising parameters etc., I would like to have a function for r/w functions using SPI.

For my SPI_Write function:

bool SPI_Write(SPI_Handle spi_handle, SPI_Params spi_params,
                                    SPI_Transaction spi_transaction, uint8_t size,
                                    uint8_t *txBuffer)
{

    SPI_Params_init(&spi_params);
    spi_params.transferMode = SPI_MODE_BLOCKING;
    spi_params.bitRate = 10000000;
    spi_params.dataSize = 8;


    spi_handle = SPI_open(0, &spi_params);

    if (!spi_handle) {
        // Error opening SPI
        return false;
    }

    spi_transaction.count = size;
    spi_transaction.txBuf = txBuffer;
    spi_transaction.rxBuf = NULL;

    if(!SPI_transfer(spi_handle, &spi_transaction))
    {
        return false;
    }

    SPI_close(spi_handle);

    return true;
}

For my SPI_Read function:

bool SPI_Read(SPI_Handle spi_handle, SPI_Params spi_params,
                                   SPI_Transaction spi_transaction, uint8_t size,
                                   uint8_t *rxBuffer)
{

    SPI_Params_init(&spi_params);
    spi_params.transferMode = SPI_MODE_BLOCKING;
    spi_params.bitRate = 10000000;
    spi_params.dataSize = 8;


    spi_handle = SPI_open(0, &spi_params);

    if (!spi_handle) {
        // Error opening SPI
        return false;
    }

    spi_transaction.count = size;
    spi_transaction.txBuf = NULL;
    spi_transaction.rxBuf = rxBuffer;

    if(!SPI_transfer(spi_handle, &spi_transaction))
    {
        false;
    }

    SPI_close(spi_handle);

    return true;
}

In turn, my driver for the LPS22HB consists of:

SPI_Transaction LPS22HB_SpiTransactionHandle;
SPI_Handle LPS22HB2_SpiHandle;
SPI_Params  LPS22HB_SpiParams;


#define TOGGLE_CS                               GPIO_write(Board_GPIO_TEST_DIO25, 0)
#define RELEASE_CS                              GPIO_write(Board_GPIO_TEST_DIO25, 1)

static void LPS22HB_Mem_Write(uint8_t reg, uint8_t *dataW, uint8_t size)
{

    uint8_t spiReg = reg;
    TOGGLE_CS; //sets the CS low

    SPI_Write(LPS22HB_SpiHandle, LPS22HB_SpiParams, LPS22HB_SpiTransactionHandle, 1, &spiReg);

    SPI_Write(LPS22HB_SpiHandle, LPS22HB_SpiParams, LPS22HB_SpiTransactionHandle, size, dataW);

    RELEASE_CS; //sets the CS high

}

static void LPS22HB_Mem_Read(uint8_t reg, uint8_t *dataR, uint8_t size)
{
    uint8_t spiBuf[1] = {0};
    spiBuf[0] = reg | 0x80;
    uint8_t i;

    TOGGLE_CS; //sets the CS low

    SPI_Write(LPS22HB_SpiHandle, LPS22HB_SpiParams, LPS22HB_SpiTransactionHandle, 1, spiBuf);

    SPI_Read(LPS22HB_SpiHandle, LPS22HB_SpiParams, LPS22HB_SpiTransactionHandle, size, dataR);

    RELEASE_CS; //sets the CS high
}

I am then trying to read the chip_id ("Who am I" of the sensor), which should be 0xB1, using the following code segment:

LPS22HB_Mem_Read(0x0f, ui8dummy, 1);

uint8_t ui8dummy[2]

if(strcmp(ui8dummy, "D") != 0)
{
return false;
}

When I read the chip-ID, I get zero, when I expect a value of 0xb1, given by the datasheet. I have debugged the SPI R/W code extensively. I have added breakpoints to the SPI_W/R functions and can guarantee that no errors are raised (the functions do not return false). I am using a software chip-select, given by the "toggle" and "release" macros. I can confirm my CS and clock works, as I've checked this on a scope. I am using the uartEcho example from the CC1310 SDK of version 20.02.07.

Are there any glaring errors in my driver for it to not work?

  • Hi Suvashan,

    The wrapper functions look okay. 

    1. Please can you check if the clock pins are being used by any other peripheral.

    2. If this is a custom board, please make please check if the pins have been puleld up or down.

    3. Also, has SPI_Init() been called? The wrappers only contain SPI_params_init(). 

    Regards,

    Sid

  • Hi Sid

    Apologies, but I can confirm that there is a clock now, after help from a colleague of mine.

    Regarding the SPI_init(), this is called in the mainThread. I have rewritten the SPI_Read function (to include a buffer for transmission of the register address), as follows:

    bool SPI_Read(SPI_Handle spi_handle, SPI_Params spi_params,
                                       SPI_Transaction spi_transaction, uint8_t size,
                                       uint8_t *rxBuffer, uint8_t *txBuffer)
    {
    
        SPI_Params_init(&spi_params);
        spi_params.transferMode = SPI_MODE_BLOCKING;
        spi_params.bitRate = 10000000;
        spi_params.dataSize = 8;
    
    
        spi_handle = SPI_open(0, &spi_params);
    
        if (!spi_handle) {
            // Error opening SPI
            return false;
        }
    
        spi_transaction.count = size;
        spi_transaction.txBuf = txBuffer;
        spi_transaction.rxBuf = rxBuffer;
    
        if(!SPI_transfer(spi_handle, &spi_transaction))
        {
            false;
        }
    
        SPI_close(spi_handle);
    
        return true;
    }

    Thus, my resulting LPS22HB-Read function would be

    static void LPS22HB_Mem_Read(uint8_t reg, uint8_t *dataR, uint8_t size)
    {
    reg |= 0x80;
    
    
    TOGGLE_CS; //sets the CS low
    
    SPI_Read(LPS22HB_SpiHandle, LPS22HB_SpiParams, LPS22HB_SpiTransactionHandle, size, dataR, &reg);
    
    RELEASE_CS; //sets the CS high
    }

    I've tested this and it does not work. May I ask, if SPI_Transfer is used, and both the rx and tx buffers are not null (or I'm not sure if that even matters), how many clock pulses are transmitted to the slave device? Given I am working with 8-bit data and a size of 1, will there be 16 clock pulses (8 for TX and 8 for RX)? 

  • Hi Suvashan,

    By default the transmission is full duplex, the controller data sends data on POCI(MOSI) and peripheral sends its data on PICO(MISO) so I would assume there are only 8 clock pulses needed (possibly more depending on the frame format). 

    This is the default frame format set by the SPI driver.

      

    You could use the CSN pin from the SPI hardware itself, that should control the CS pin as needed.

    Regards,

    Sid

  • Hi Sid

    Thank you for that info. Moving forward from this knowledge, if we observe the timing diagram below for the pressure sensor itself, it specifies a CPOL = 1 and CPHA = 0. Furthermore, to read from a register, the master must write the register address to the slave. Then, the master MUST CONTINUE GENERATING CLOCK PULSES to allow the slave (sensor) to transmit the value stored in the desired register. Thus, in total, the master must transmit one byte but generate 16 clock pulses.

    For such a scenario, I have tried solely transmitting the data (register's address) to the slave (obviously using SPI_transfer()), where I have left the rxBuffer to be NULL. Then, I have tried using SPI_transfer(), with just an rxBuffer, setting the txBuffer to NULL, to receive the given data. This did not work, and the rxBuffer continues to read zero. Is there a smarter way to do this?

  • Hi Suvashan,

    I see that the microwire format is the closest to this. Please can you try that SPI_MW as the spiParams.frameFormat.

    Please check the section 22.4.4 in the technical reference manual, it provides all the frame formats that the device supports. 

    www.ti.com/.../swcu192.pdf

    Regards,

    Sid