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
AndrasToth
Associate III

 

I found a solution for this problem. It combines @AScha.3 suggestion with a little bit of a hardware tweaking. It seems that inspite of the statement from the datasheet that the device can tolerate 3.3V it doesn't like this voltage level. Therefore, I connected the lines with a voltage level translator to get 1.8V (I used LFS2040). With the following code I can read the correct value from the WhoAmI register (I can read 0x47 on the MISO):

  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 */

 Thank you very much for your helps and suggestions guys!