Skip to main content
hashem ahmadi
Associate
June 27, 2017
Solved

SPI Receive problem

  • June 27, 2017
  • 4 replies
  • 1696 views
Posted on June 27, 2017 at 06:45

Hi all,

I am trying to read a four bytes register from TDC-GP30 ultrasonic flow converter using HAL_SPI_Receive function. Below is the code that I am using for reading the register contents:

/*******************************************************************************

* Function Name: gp30_read_n_bytes

* Parameters: n_bytes = how many bytes should be read

* read_opcode = read opcode of the device

* read_addr = read address of the device

*

* Return: n bytes from the specified read address

*

* Description: Reads n bytes from an address in GP30

*

******************************************************************************/

float gp30_read_4_bytes(uint8_t read_opcode, uint8_t read_addr)

{

uint32_t Result_read = 0x00000000;

uint8_t Result_read_buff = 0x00;

GP30_SPI_enable();

HAL_SPI_Transmit(&hspi1,&read_opcode,1,100);

HAL_SPI_Transmit(&hspi1,&read_addr,1,100);

HAL_SPI_Receive(&hspi1,&Result_read_buff,1,100);

Result_read |= (Result_read_buff<<24);

HAL_SPI_Receive(&hspi1,&Result_read_buff,1,100);

Result_read |= (Result_read_buff<<16);

HAL_SPI_Receive(&hspi1,&Result_read_buff,1,100);

Result_read |= (Result_read_buff<<8);

HAL_SPI_Receive(&hspi1,&Result_read_buff,1,100);

Result_read |= (Result_read_buff);

GP30_SPI_disable();

return Result_read;

}

The problem is that I cannot receive all four bytes. For example one register contains 0x12345678 and when I read its content I receive 0x12345600 all the time. Its receiving fine for some other values but not for all values.

    This topic has been closed for replies.
    Best answer by hashem ahmadi
    Posted on July 02, 2017 at 19:27

    Well my problem become solved simply by changing the input type from float to uint32_t.  

    4 replies

    Mathew Hystek
    Visitor II
    July 2, 2017
    Posted on July 02, 2017 at 12:15

    Hi Hashem

    I am having problems too, all though I dont have a full understanding of it.

    But I would imagine how it works is as follows:

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#ga02ec86e05d0702387c221f90b6f041a2

    (SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)

    When you use

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#ga02ec86e05d0702387c221f90b6f041a2

    , the clock pin outputs based on the size of the data (hspi1.Init.DataSize) and the

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#ga02ec86e05d0702387c221f90b6f041a2

     multiplier parameter (which is the third parameter,

    uint16_t Size

    )

    If your hspi1.Init.DataSize is set to 10bit, and the multiplier is set to 1, then the clock pin will output 10 times.

    0690X00000607GzQAI.png

    If the multiplier is set to 2, then the clock pin will output 20 times

    0690X00000607H0QAI.png

    However the 

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#ga02ec86e05d0702387c221f90b6f041a2

     parameter (

    uint8_t *pData) will only transmit on the first 10 bits.

    Here I am sending 0xF, 10bit data size, 2 x multiplier

    0690X00000607KgQAI.png

    based on the datasheet of the device i am talking to, I cannot use 2 x multiplier. Why? because it will send data during 

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#ga02ec86e05d0702387c221f90b6f041a2

    . And to my understanding, 

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#ga02ec86e05d0702387c221f90b6f041a2

     is non blocking mode, which means the application waits for 

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#ga02ec86e05d0702387c221f90b6f041a2

     to finish before proceeding with the rest of the program/application.

    So I would image I would use 

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#ga02ec86e05d0702387c221f90b6f041a2

     with a multiplier of 1, where the clock sends 10 bits.

    Then I would use

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#gafdf43dbe4e5ef225bed6650b6e8c6313

     with also a multiplier of 1, causing the clock to sen additional 10bits and also listening on the MISO line.

    But what actually happens when you use 

    https://developer.mbed.org/users/EricLew/code/STM32L4xx_HAL_Driver/docs/tip/group__SPI__Exported__Functions__Group2.html#gafdf43dbe4e5ef225bed6650b6e8c6313

    , it does not send any additional bits on the clock (otherwise i would see it on the oscilloscope) and instead goes to some sort of infinite loop called HardFault_Handler0690X00000607LFQAY.png

    Why? this is the third device in a row I have used that has the exact same problem with SPI under the STM32 family.

    the varibles I am using:

    uint8_t SpiTransmit = 0xF;

    uint8_t SpiReceive;

    calling the HAL functions in main while(1)

    HAL_SPI_Transmit(&hspi1, &SpiTransmit, 1, 10);

    HAL_SPI_Receive(&hspi1, &SpiReceive, 1, 10);

    HAL_Delay(100);

    initiation code generated from STM32CubeMX 4.19

    compiled using Keil uVision v5.23

    0690X00000607LKQAY.png0690X00000607GIQAY.png
    S.Ma
    Principal
    July 2, 2017
    Posted on July 02, 2017 at 16:13

    When using spi in bidir mode, the spi clock generation comes from sending out data. Some spi may have rx an tx fifo up to 32 bit chunck capacity. First is to properly write de SPI.DR in 8 or 16 bit mode which will be fifoed. Then the properly configured RXNE will tell when chunk has been received and ready for reading.

    There should be some details in the right STM32 Reference Manual.

    Mathew Hystek
    Visitor II
    July 3, 2017
    Posted on July 03, 2017 at 11:48

    I changed

    hspi1.Init.DataSize to 8bit, and I am now getting the

    /external-link.jspa?url=https%3A%2F%2Fdeveloper.mbed.org%2Fusers%2FEricLew%2Fcode%2FSTM32L4xx_HAL_Driver%2Fdocs%2Ftip%2Fgroup__SPI__Exported__Functions__Group2.html%23gafdf43dbe4e5ef225bed6650b6e8c6313

    to send the clock signals, but only 16 in total instead of

    The only problem is, the data that will be sent down the MISO line will be 10 bit.

    It seems

    /external-link.jspa?url=https%3A%2F%2Fdeveloper.mbed.org%2Fusers%2FEricLew%2Fcode%2FSTM32L4xx_HAL_Driver%2Fdocs%2Ftip%2Fgroup__SPI__Exported__Functions__Group2.html%23gafdf43dbe4e5ef225bed6650b6e8c6313

    cannot pass on anything more then 8 bit.

    So I added another line

    /external-link.jspa?url=https%3A%2F%2Fdeveloper.mbed.org%2Fusers%2FEricLew%2Fcode%2FSTM32L4xx_HAL_Driver%2Fdocs%2Ftip%2Fgroup__SPI__Exported__Functions__Group2.html%23gafdf43dbe4e5ef225bed6650b6e8c6313

    and got another 8 bit clock signals.

    Which means if I have two different variables i can then work out the 10bit communicationreceived.

    So for anyone one else out there trying to work this out, only use 8bit parameter for

    hspi1.Init.DataSize

    Thank you KIC8462852 EPIC204278916 for your assistance.

    Mathew Hystek
    Visitor II
    July 6, 2017
    Posted on July 06, 2017 at 11:05

    Just wanted to say the above worked as intended, just have to change 

    uint8_t SpiReceive;

    managed to get values by using unsigned char SpiReceive; instead.

    hashem ahmadi
    hashem ahmadiAuthorBest answer
    Associate
    July 2, 2017
    Posted on July 02, 2017 at 19:27

    Well my problem become solved simply by changing the input type from float to uint32_t.  

    M.R.Abedini
    Visitor II
    July 9, 2019

    hello hashem

    change the type variable