Skip to main content
Explorer II
April 15, 2024
Question

SPI - not recieving a response on MISO line

  • April 15, 2024
  • 5 replies
  • 6250 views

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

 

 

 

 

    This topic has been closed for replies.

    5 replies

    Graduate II
    April 15, 2024

    the most common problem is that you try to read too fast after sending command

    try:

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
    HAL_SPI_Transmit(&hspi1, (uint8_t *)data, 2, 100);

     

    HAL_Delay(100);  //keep lowering delay to see if it still works or try higher setting


    HAL_SPI_Receive(&hspi1, (uint8_t *)spi_buff, 2, 100);

    HAL_Delay(100); 
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

     

    also try interrupt mode sometimes it works better

     

    Super User
    April 15, 2024

    The datasheet doesn't suggest any need for delays:

    AndrewNeil_0-1713194625358.png

     

    Graduate II
    April 15, 2024

    look closer the SDO line is shifted a little bit to the right

    so maybe you need only HAL_Delay(1) to do the job

     

    he also deselects the chip too fast

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

    before it can process the response.

    if you are pounding it so fast in while() loop it might not work.

    the response is never instantaneous it needs time to process data and request.

    Super User
    April 15, 2024

    Have you used a logic analyser or oscilloscope to see what's actually happening on the wires?

    Explorer II
    April 17, 2024

    Yes, I checked every line with oscilloscope and everything were working except the MISO line. On the MISO line I couldn't see anything.

    Graduate II
    April 15, 2024

    Test your code on e.g. a Nucleo board and connect MOSI to MISO with a jumper wire.

    Super User
    April 15, 2024

    Hi,

    (after 30 mins on ds ...)

    1. spi clk mode is wrong:

    AScha3_0-1713198839245.png

    set : cpol hi + cpha 2edge (as i see from this timing diagram)

    AScha3_1-1713199138329.png

    + set in Cube/ioc : 

    AScha3_3-1713200235542.png

     

    2. command / response

    AScha3_2-1713199377814.png

    I would use :

     

     

    /*HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
     uint16_t Size, uint32_t Timeout) */
    uint8_t TxData[16], RxData[16];
    so:
    TxData[0] = 0x91 ; // read : whoami
    HAL_SPI_TransmitReceive(&hspi1, TxData, RxData, 2 , 50);

     

     

    The response should be in Rxdata[1] then.

     

    3. set spi clk to 1 MHz or so, faster is no problem - if it works fine.

     

    Explorer II
    April 17, 2024

    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?

    Super User
    April 17, 2024

    @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?

    Explorer II
    April 18, 2024