cancel
Showing results for 
Search instead for 
Did you mean: 

LIS3DSH accelerometer only sending 0xFF or 0x00 over SPI - STM32F407 discovery board

SAMBA.1
Associate II

I've been grappling with the SPI bus for weeks on end to no avail. I've made my own libraries for UART, ADC, Timer etc successfully, so I'm fairly certain it's not any of the common pitfalls like not enabling the clock or misconfiguring the GPIO. I decided to cave and use the HAL libraries provided by ST themselves, and I'm still seeing the same issue.

Here's my initialization code:

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
    {
      Error_Handler();
    }
 
  GPIO_InitTypeDef GPIO_InitStruct;
  __HAL_RCC_SPI1_CLK_ENABLE();
 
  GPIO_InitStruct.Pin = (1<<5)|(1<<6)|(1<<7);
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
  GPIO_InitStruct.Alternate = 5;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  GPIO_InitStruct.Pin = (1<<3);
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  GPIO_InitStruct.Alternate = 0;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

And then here's the relevant part of my application code. It waits for me to press the button (w/ a crude debounce counter) and then outputs a UART message to my computer with the value returned from the accelerometer (8-bit value converted to a string by my int82string function). I'm reading address 0x0F (making sure to send 0x8F so its a read function), which is its WHO_AM_I register. I should be getting back a value of 63 0x3F. Instead it's nothing but 255 or 0.

 while(1){
      if (HAL_GPIO_ReadPin(GPIOA, B1_Pin) == GPIO_PIN_SET) {
          if (dbounceCtr > 100000) {
 
              HAL_GPIO_WritePin(GPIOE, 3, GPIO_PIN_RESET);
              //HAL_SPI_TransmitReceive(&hspi1, &dummy, &response, 1, timeout);
              //HAL_SPI_Receive(&hspi1, &response, 1, timeout);
              HAL_SPI_TransmitReceive(&hspi1, &address, &response, 1, timeout);
              HAL_SPI_TransmitReceive(&hspi1, &dummy, &response, 1, timeout);
              HAL_GPIO_WritePin(GPIOE, 3, GPIO_PIN_SET);
 
              int82string(response, accel); //convert accelerometer's output to string
 
              HAL_UART_Transmit(&huart1, message1, strlen(message1), timeout);
              HAL_UART_Transmit(&huart1, accel, strlen(accel), timeout);
 
              dbounceCtr = 0;
          }
          dbounceCtr++;
      }
  }

My understanding is I need to transmit the address I want to read, and then send a dummy address so the clock signal continues while I receive the actual value. You can see from my commented lines that I've also tried doing another dummy read cycle beforehand, but nothing seems to stick.

Any help would be appreciated. Every answer online has strangely led nowhere. My original libraries do exactly what they do, so I tried using the HAL code and once again I'm doing exactly what others do and getting garbage. Has anyone else run into a similar issue? Anyone familiar with ST HAL libraries seen this?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Looks like you're calling HAL_SPI_Init prior to enabling the clock, at least in the code you provided. Probably not the issue.

> HAL_GPIO_WritePin(GPIOE, 3, GPIO_PIN_RESET);

This doesn't set PE3 to 0. You want either of the following:

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, 1 << 3, GPIO_PIN_RESET);

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

3 REPLIES 3
TDK
Guru

Looks like you're calling HAL_SPI_Init prior to enabling the clock, at least in the code you provided. Probably not the issue.

> HAL_GPIO_WritePin(GPIOE, 3, GPIO_PIN_RESET);

This doesn't set PE3 to 0. You want either of the following:

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOE, 1 << 3, GPIO_PIN_RESET);

If you feel a post has answered your question, please click "Accept as Solution".
SAMBA.1
Associate II

The initialization code I copied and pasted out of order here, it's correct in the actual code.

I'll check the WritePin, thanks! I know I was correctly setting it in the library I made but this may be my issue when using the HAL.

This was it!!! Thank you so much! I can't tell you how frustrating this has been, I can finally move on. The healing process can begin. :relieved_face: