T0K4M4K
T0K4M4K

Reputation: 11

stm32 SPI receive only mode need a transmit?

sorry in advance, i am new at this kind of projects.
I tried to implement a connection to an ADC (LTC1609) via SPI. I just want to get the data from the ADC as quick as possible. The ADC has just a output-line, so i chose the "read only mode". But i also tried to use the HAL_SPI_TransmitReceive funktion because i remembered that the spi exchange starts with writeing in the transmit register (at least with the HCS12). The ADC needs also some additional signals changes between pulling down the NSS and starting the spi connection so i put the NSS in software mode.

The Cofiguration looks like this:

   static void MX_SPI1_Init(void)
{
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
  hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }   
}

I write a funktion to read from ADC and store the data.

void LTC1609_ADU_Read(uint8_t *data)
{
        uint8_t buffer_rx[2];

        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);    // NSS low  (Pin PA4) Start 
        HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, 0);    // ADU R/NC low  (Pin PG6) Start conversion
        delay_hns (1);                              // wait 1us (10 x 100ns)
        HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, 1);    // ADU R/NC high  (Pin PG6)
       
        if(HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_8) == 1)    // /BUSY is high? -> start SPI
        {
            if(HAL_SPI_Receive(&hspi1, buffer_rx,2,10)!= HAL_OK);
            {
                SPI_error = HAL_SPI_GetError(&hspi1); // get the SPI error
                Error_Handler();                      // stop in error
            }
        }

        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1); // Set ADU /CS high  (Pin PA4) fin
        *data = buffer_rx[1];           // store received data
}

In the while(1) i called it like this with a delay of 100 ms for testing:

LTC1609_ADU_Read(&buffer_A_rx); 

Problem:
The uC (STM32L4R5ZIT6P) dont start the SPI clk to trigger out the data from ADC. Also the Clock polarity is somtimes low (like i want) and sometimes high [could also be a messuring problem, i messure it with a sheep logic analyser 24Mhz 8CH from amazon]. If i start the programm, it runs into the error handler and the errorcode is 0x20. I found this explaining:
HAL_SPI_ERROR_FLAG 0x00000020U /*!< Flag: RXNE,TXE, BSY */

Can anyone give me a tip on what could be the reason? Did iam doing something wrong or could the hardware be damaged? Thanks in advance!

screenshot signals without clk

Upvotes: 1

Views: 1418

Answers (1)

Armandas
Armandas

Reputation: 2396

One problem that I see in your code is that you check the BUSY pin immediately after setting R/C high and abort the transaction if BUSY is low.

According to the datasheet, BUSY line may be low for up to 3 us (t3).

Try waiting for the busy pin to go high, for example by adding a loop as shown below.

void LTC1609_ADU_Read(uint8_t *data)
{
    uint8_t buffer_rx[2];

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 0);  // NSS low  (Pin PA4) Start
    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, 0);  // ADU R/NC low  (Pin PG6) Start conversion
    delay_hns(1);                             // wait 1us (10 x 100ns)
    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, 1);  // ADU R/NC high  (Pin PG6)

    uint8_t retries = 0;
    do {
        delay_hns(1);
    } while (HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_8) == 0 && ++retries < 5);

    if (HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_8) == 1)  // /BUSY is high? -> start SPI
    {
        if (HAL_SPI_Receive(&hspi1, buffer_rx, 2, 10) != HAL_OK)
        {
            SPI_error = HAL_SPI_GetError(&hspi1);  // get the SPI error
            Error_Handler();                       // stop in error
        }
    }

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, 1);  // Set ADU /CS high  (Pin PA4) fin
    *data = buffer_rx[1];                     // store received data
}

Also, there is a stray ; in your code, on this line:

if(HAL_SPI_Receive(&hspi1, buffer_rx,2,10)!= HAL_OK);

Upvotes: 0

Related Questions