Skip to main content
Associate III
June 28, 2024
Question

LIS2D12

  • June 28, 2024
  • 13 replies
  • 4629 views

I use LIS2DS12 

This is my init function

 

 

 

void LIS2DS12_Init(void)
{
	uint8_t ctrl_1 = 0x72; //0111 for 6.4kHz ODR [7:4], 00 for 2g [3:2], 1 for high frequency available[1], 0 for BDU not activated [0]
	uint8_t ctrl_2; // [6] for soft_reset, [1] for disable I2C, [0] for 4 wires SPI
	HAL_StatusTypeDef ret;

	ret = spi_read_LIS2DS12(CTRL2_ADDR, &ctrl_2);
	ctrl_2 |= 0x42; // [6] for soft_reset, [1] = 1 for disable I2C, [0] = 0 for 4 wires SPI
	ret = spi_write_LIS2DS12(CTRL2_ADDR, &ctrl_2);

	//reset the accelerometer
	ret = spi_write_LIS2DS12(CTRL1_ADDR, &ctrl_1);

	//set the accelerometer to measurement mode


	spi_read_LIS2DS12(CTRL1_ADDR, &ctrl_1);
	spi_read_LIS2DS12(CTRL2_ADDR, &ctrl_2);
}

 

 

 

with read and write : 

 

 

 

HAL_StatusTypeDef spi_write_LIS2DS12(uint8_t regAddr, uint8_t *pData)
{
	HAL_StatusTypeDef ret;
	uint8_t address = regAddr & 0x7F;

	uint8_t sendData[2] = {address, *pData};
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 0);

	ret = HAL_SPI_Transmit(&hspi2, sendData, 2, 20);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 1);

	return ret;
}
HAL_StatusTypeDef spi_read_LIS2DS12(uint8_t regAddr, uint8_t *pData)
{
	HAL_StatusTypeDef ret;
	uint8_t address = regAddr | 0x80;

	uint8_t sendData[2] = {address, 0};
	uint8_t receiveData[2] = {0};

	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 0);

	ret = HAL_SPI_TransmitReceive(&hspi2, sendData, receiveData, 2, 50);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 1);

	*pData = receiveData[1];

	return ret;
}

 

 

 

The protocol for SPI transmission is 

fru999_0-1719563774185.png

fru999_1-1719563790647.png

But my Register always equal to 0. ret = HAL_OK.

I don't understand why :)

Can you help me

 

13 replies

Andrew Neil
Super User
June 28, 2024

@fru999 wrote:

The protocol for SPI transmission is 

fru999_0-1719563774185.png

fru999_1-1719563790647.png


So have you used a logic analyser or oscilloscope to see if what's actually happening in your hardware matches those ?

among other things, you haven't told us what board(s) you're using - please see:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
AScha.3
Super User
June 28, 2024

Maybe you have to adjust your setting for the SPI:

set it to 16bit data , (Motorola) MSB first, and clock CPOL high + CPHA 2 edge .

Try...  (and write/read uint_16  size , 1 x . (not 2 bytes, as now.) )

 

+

if not working: verify with scope, what you do (if possible) (as Andrew said...)

"If you feel a post has answered your question, please click ""Accept as Solution""."
fru999Author
Associate III
June 28, 2024

Why do you think that will fix my problem (I just want to understand) 

fru999Author
Associate III
June 28, 2024

I it is 16bit that means that the 8 LSB are the register and the 8 last are the data ?

fru999Author
Associate III
June 28, 2024

I did a mistake this is not the solution
I get the CPHA and CPOL values

AScha.3
Super User
June 28, 2024

:)

You can select in these box menu -> not the solution, Then can check another for solution...

"If you feel a post has answered your question, please click ""Accept as Solution""."
fru999Author
Associate III
June 28, 2024

do you think my read and write protocol are good ?

AScha.3
Super User
June 28, 2024

I dont know...(just came back.).

But at first your clock/timing needs to match the device, you wanna talk to. (timing->phase = is rising or falling edge the correct point, to get the data).

Then transmit/receive , to write to device (and get response in same access, if device can do this.) ->

In your timing pic , for SPI-read , it shows like this; 

transmitted word/upper 8 bits is address, response (read=answer) comes in received word, lower 8bits ;

so you always have to do a (16bit) word transmit/receive , and set the important byte (= address), and in received word only use the lower byte (=response).

"If you feel a post has answered your question, please click ""Accept as Solution""."
fru999Author
Associate III
June 28, 2024

but it is like a 16 bit receive/transmit thanks to my list of 8bit no ?

 

fru999Author
Associate III
June 28, 2024

fru999_0-1719570923550.pngfru999_1-1719570937157.png

my CS:

fru999_2-1719570962846.png

 

Andrew Neil
Super User
June 28, 2024

@fru999 - again:

Have you used a logic analyser or oscilloscope to see if what's actually happening in your hardware matches the protocol spec diagrams you posted ?

Among other things, you haven't told us what board(s) you're using - please see:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
fru999Author
Associate III
July 18, 2024

Read underneath the picture, it is 8 bits the data size 
But now the problem is that when I am in reading mode, after transmit receive, the receive data are equal to the transmit data... 
Do you have an idea why? 

AScha.3
Super User
July 18, 2024

Did you set it to 16bit frame at last ?

"If you feel a post has answered your question, please click ""Accept as Solution""."
fru999Author
Associate III
July 18, 2024

No, I have changed it and i always have hal_error and i have worked with another accelerometer wich description of SPI was the same and the data size was 8

fru999Author
Associate III
July 18, 2024

and this is the definition of the function in STM32 CUBE :

HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,

uint16_t Size, uint32_t Timeout)