cancel
Showing results for 
Search instead for 
Did you mean: 

SPI - not recieving a response on MISO line

AndrasToth
Associate III

Hello everyone!

I'm trying to communicate with a slave device (ICM-42688-P: https://invensense.tdk.com/wp-content/uploads/2020/04/ds-000347_icm-42688-p-datasheet.pdf), but I don't recieve anything on the MISO line. I'm using the nucleo-wb55rg for the master device. The ICM-42688 typically needs 1.8V for the VDD and VDDIO, but the datasheet says it can be used between the range of 1.71V and 3.6V. Therefore I just used the nucleo's 3.3V pin output to power both. After that I configured the SPI following the datasheet:

AndrasToth_2-1713191910613.png

AndrasToth_3-1713191981610.png

The code I wrote for excercise is a read from the whoAmI register, which is at address 0x75 and contains the value of 0x47. However I only get 0s from the MISO line.

The code from main.c:

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

/* Configure the peripherals common clocks */
  PeriphCommonClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USB_PCD_Init();
  MX_MEMORYMAP_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  char spi_buff[16] = {0};
  uint8_t addr = 0x00;
  uint8_t data[2] = {0};

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

  // Set bank addr 0x76
  addr = 0x76;
  data[1] = 0x00 | addr;
  data[0] = 0x00;
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
  HAL_SPI_Transmit(&hspi1, (uint8_t *)data, 2, 100);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

  //Soft reset addr 0x11
  addr = 0x11;
  data[1] = 0x00 | addr;
  data[0] = 0x01;
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
  HAL_SPI_Transmit(&hspi1, (uint8_t *)data, 2, 100);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  HAL_Delay(1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  // Get WhoIAM addr 0x75, value 0x47
	  addr = 0x75;
	  data[1] = 0x80 | addr;
	  data[0] = 0;
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
	  HAL_SPI_Transmit(&hspi1, (uint8_t *)data, 2, 100);
	  HAL_SPI_Receive(&hspi1, (uint8_t *)spi_buff, 2, 100);
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  }
  /* USER CODE END 3 */
}

What am I missing here? Did I messed up something in the code or it is more likely a hardver issue?

 

I am looking forward for your answers!

 

Yours faithfully,

AndrasToth

 

 

 

 

20 REPLIES 20

I tried out your suggestion and it worked (on both cpol low & cpha 1 and cpol high & cpha 2). Now I can see data on the MISO line on the oscilloscope and the debugger. However I read on the MISO line 0x40 in spite of the WhoAmI register should contain 0x47. Do you have and idea where that 0x07 goes?


@AndrasToth wrote:

 I read on the MISO line 0x40 in


Is that the value you see on your scope, or the value you receive in your software?

I read the 0x40 in the software and I can see the following on the oscilloscope:

OscilloscopeOscilloscope

 

>Do you have and idea where that 0x07 goes?

Nirwana !  

+

Try (with settings , as i wrote) to read some other registers , that have a known (default) value .

Just to verify , the chip is now "understanding" the spi input and response is also as it should be.

(Or to see, whats still wrong in response.)

+

And dont touch the spi lines with a scope probe at 1:1 setting !

Better without scope then, just see in debug the response - thats what we want anyway.

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

I configured it as you suggested (cpol high & cpha 2) using STM32CubeIde 1.13.2, but I can't find in the advanced parameters the Master keep IO state option.

AndrasToth_0-1713352839515.png

Which .c file do I have to write a code that can manually enable this setting?

it can also communicate using I2C ?

 

what do not try this option, first see if there is any response, scan all 255 addresses

HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);

this way you know it is not faulty device.

 

do you have Arduino?  it has library to try and see if it works, this will be very simple and easy to check it.

Arduino library supports both I2C and SPI communication with the ICM-42688

I am not sure about - WB55 cpu i dont have (and i cannot look here - i am at work),

but most SPI have this setting : in Advanced parameters (in Cube) you should see it (or this SPI dont have it , then also ok.)

Its just : to keep the spi lines at its active state, between transmissions etc. , to avoid target "see" a extra pulse.

If you dont see this setting , its ok. (Then this spi should do it anyway.)

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

@AndrasToth wrote:

 I can see the following on the oscilloscope:


 What's that looking at?! 😳

You need to look at the full SPI transaction - is the slave actually sending 0x40, or 0x47, or ... ?

Also, does what your STM32 actually sends on the wires match the slave specs?

Does your scope have the capability to decode SPI?

Surely, a Tektronix scope has a way to capture a proper screenshot?

I tried with different registers and the same problem occures, also I tried to lower the Baud Rate, but it's all the same.

>What's that looking at?!

It was the reply on MISO line to the read command, but I'll capture a better one.

>You need to look at the full SPI transaction - is the slave actually sending 0x40, or 0x47, or ... ?

I did and that was the only signal.

>Also, does what your STM32 actually sends on the wires match the slave specs?

Yes it should be. The first bit of the first byte declare that the command will be a read(1) or write(0) command and next 7 bit is the address, which for the WhoAmI is 0x75.  

AndrasToth_0-1713359599926.png

The code I wrote for the transaction:

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  TxData[0] = 0x80 | 0x75;
	  TxData[1] = 0x00;
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
	  HAL_SPI_TransmitReceive(&hspi1, TxData, RxData, 2, 50);
	  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  }
  /* USER CODE END 3 */

Therefore I don't think this will be the problem, but I might be wrong here.

>Does your scope have the capability to decode SPI?

It can't unfortunately, I can only look at it deciper the signal myself.

 

The following pictures from the oscilloscope:

CLK:

AndrasToth_1-1713362363724.png

CS:

AndrasToth_2-1713362385451.png

MOSI ( 0x75 | 0x80 is 0b11110101 and I think this signal is exactly the same):

AndrasToth_3-1713362404748.png

MISO:

AndrasToth_4-1713362417730.png