AnsweredAssumed Answered

STM32L476VG HAL - HAL_SPI_TransmitReceive reads same data it sent

Question asked by Phil Pemberton on Jul 6, 2016
Latest reply on Jul 11, 2016 by FTITI.Walid
I'm trying to access an SPI device using the HAL library on an STM32L476VG chip. The initialisation code was generated with STM32Cube 4.15.1.

The problem is that the SPI peripheral correctly sends data, and I can see the transaction on my logic analyser, but the data returned by HAL_SPI_TransmitReceive (in rxData) is always the same as the data which was sent.

There are no short circuits between MOSI and MISO (first thing I checked); and as I said, the whole transaction looks fine on the analyser. I get valid data on MOSI and MISO. It's just that the MCU apparently can't see what the SPI device is sending back.

Here is my SPI initialisation code:

/* SPI2 init function */
void MX_SPI2_Init(void)
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCPolynomial = 7;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)

And my SPI transaction code:

static ADS1120_RESULT prv_ReadReg(ADS1120_Handle    *adsHandle,
                                  const uint8_t startReg,
                                  const uint8_t count,
                                  uint8_t *data)
    // Reserve space for the longest possible transaction
    uint8_t TXN[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 };  // 00s are padding for read bytes
    uint8_t readblock[5];
    // calculate the command byte
    TXN[0] = 0x20 /* 0b00100000 */ | (startReg << 2) | (count - 1);
    // Flush the SPI receive FIFO
    if (HAL_SPIEx_FlushRxFifo(adsHandle->spiHandle) != HAL_OK) {
        return ADS1120_ERR_COMMS;
    // Select the ADS1120
    HAL_GPIO_WritePin(adsHandle->gpioCS, adsHandle->gpioPinCS, GPIO_PIN_RESET);
    // Send the transaction
    if (HAL_SPI_TransmitReceive(adsHandle->spiHandle, TXN, readblock, count + 1, 200) != HAL_OK) {
        // Failure.
        // Deselect the ADS1120.
        HAL_GPIO_WritePin(adsHandle->gpioCS, adsHandle->gpioPinCS, GPIO_PIN_SET);
        return ADS1120_ERR_COMMS;
// Here 'readblock' should contain what came back from the 1120, but instead it is equal to TXN

    // Deselect the ADS1120.
    HAL_GPIO_WritePin(adsHandle->gpioCS, adsHandle->gpioPinCS, GPIO_PIN_SET);
    // Copy the data into the user-supplied buffer
    memcpy(data, &readblock[1], count);
    return ADS1120_OK;

Can anyone see anything wrong with this, or offer any suggestions for things I could check?