Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

STM32F407 accelerometer LIS3DSH only sending 0xFF over SPI

Status
Not open for further replies.

shredder929

Junior Member level 3
Joined
Jul 1, 2019
Messages
27
Helped
1
Reputation
2
Reaction score
2
Trophy points
3
Location
Massachusetts
Activity points
408
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:

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.

Code:
  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?
 

Hi,


There is a lot of informatin missing that is urgent for clean SPI communication. Wiring, voltages, timing, values...

Thus:
Please show the relevant schematic and signal_voltage_levels and supply_voltage_levels.

Also:
* Port setup
* timing setup
* variables setup of (at least): &address, &response, &dummy, timeoout...

You know that this "Read" may happen many times per second depending on STM clock frequency.

Do you have a scope or a logic analyzer to show the communication signals? If so, show all 4 lines in one picture of at least the 16 first SCK clock cycles.

Klaus
 

Sorry, wasn't clear enough, this is using the Evaluation board. Schematic and layout for it can be found here: https://www.st.com/resource/en/user...t-with-stm32f407vg-mcu-stmicroelectronics.pdf

I'm making the fairly safe assumption that the layout is okay on the evaluation board. Port and timing setup is already shown in the code I posted. PA5, PA6, and PA7 are SPI CLK, MISO, and MOSI, and PE3 is SPI CS for the accelerometer. Clock rate for peripherals is 16MHz, scaled down by 32 for SPI communication.

Setup for variables is:

Code:
uint8_t address = (0x8F);
uint8_t dummy = (0x00);
uint8_t response = 0;
int timeout = 5000;
accel[] = "000";

Everywhere I've looked, other users set up the SPI bus and GPIO the same as I have here.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top