Skip to main content
Explorer II
August 24, 2024
Solved

Unable to perform multi-byte SPI; Single OK

  • August 24, 2024
  • 3 replies
  • 2603 views

Hello -

Board - STM32 NUCLEO-L476G

Peripheral board ADXL313 (16 byte data registers)

Interface - SPI

I  can perform single byte read, combine the 2, 8 bit values and the data is correct. Yet, when I try to perform a 2 byte SPI read, it's garbage.

This works:

uint8_t ADXL313_ReadRegister(uint8_t reg)
{
uint8_t rxData[1];
uint8_t txVal[1];
txVal[0] = (reg | 0x80);
ACC_CS_ASSERT();  // low
HAL_SPI_Transmit(&hspi3, txVal, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi3, rxData, 1, HAL_MAX_DELAY);
ACC_CS_DEASSERT(); //high

return rxData[0];
}

int16_t ADXL313_ReadDataRegister( uint8_t reg)
{
uint8_t data0 = ADXL313_ReadRegister(reg);
reg += 1;
uint8_t data1 = ADXL313_ReadRegister(reg);
return (int16_t)((data1 << 8  | data0 );
}

Using above data values are correct when doing to separate 1 byte reads and combining

But this...does NOT work:

void ADXL313_ReadDataRegister(int16_t *data)
{
uint8_t txData[1];
uint8_t rxData[2];

txData[0] = ADXL313_REG_DATAX0 | 0x80; // 0x80 to indicate read operation

ACC_CS_ASSERT(); //low
HAL_SPI_Transmit(&hspi3, txData, 1, HAL_MAX_DELAY);

HAL_SPI_Receive(&hspi3, rxData, 2, HAL_MAX_DELAY); //set for 2 byte read
ACC_CS_DEASSERT(); //high

// Combine 2 registers for data
*data = (int16_t)((rxData[1] << 8  | rxData[0]);   //DATA IS NOT GOOD
}

Can someone provide feedback on what the issue might be?

Thanks!

 

 

 

    This topic has been closed for replies.
    Best answer by roger99

    hi -

    working! not sure why this does not work:

    HAL_SPI_TransmitReceive(&hspi3, txData, rxData, 7, HAL_MAX_DELAY);

    But no matter because this does!

    HAL_SPI_Transmit(&hspi3, txData, 1, HAL_MAX_DELAY);
    HAL_SPI_Receive(&hspi3, rxData, 7, HAL_MAX_DELAY);

     

    But I think the big think from this is the "multi-byte" bit 0x40 that has to be set in addition the the read bit 0x80 with the target register.

    Thanks again.

    Gary

     

    3 replies

    Graduate II
    August 24, 2024

    Might suggest using the HAL_SPI_TransmitReceive to ensure data order and flag checking/clearing

    View signals with scope or analyzer to confirm states, ordering and timing.

    roger99Author
    Explorer II
    August 24, 2024


    Tesla DeLorean-

    Thanks for feedback. Same wrong data. I've looked at this before on scope, signals seems OK. It's a bit of a pain on a 2 chn scope as I can't trigger on CS while watching TX,RX. 8--(  But the signals were clean enough with no obvious problems.

    The rest of the ADXL device works with no issues. Just this multi-byte read is being difficult. Project uses a rather slow main clock (4MHz) and using a prescaler of 2 on SPI (2Mbits baud)

     

    Graduate II
    August 24, 2024

    Double check that behavior of the CS waveform matches the expectations of chip. Some chips require CS not be toggled between bytes, some require the opposite ("framing").

     

    Also double check that you are meeting the timing requirements on the CS signal. Chips have expectations re minimal pulse duration and perhaps its timing relative to surrounding data bits.

    roger99Author
    Explorer II
    August 24, 2024

    Thanks for this information, I will review the data sheet. But since it works well enough reading single registers do you believe this is still possible possible regarding the CS? One would think that behavior of CS with respect to all R/W operations should be uniform..?

    Graduate II
    August 24, 2024

    I'll agree that I could be wrong, if you'll agree to check if I am. :)

    roger99Author
    Explorer II
    August 25, 2024

    Hehe, that's a sly way of telling me to do some homework...game on! Thanks. Will let you know what I find.