cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Receive problem

hashem ahmadi
Associate
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.

1 ACCEPTED SOLUTION

Accepted Solutions
hashem ahmadi
Associate
Posted on July 02, 2017 at 19:27

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

View solution in original post

6 REPLIES 6
Mathew Hystek
Associate II
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
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.

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

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

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.

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.

M.R.Abedini
Associate II

hello hashem

change the type variable