0
votes

I am using an external flash memory called W25Q128FW from Winbound with a STM32L4 microcontroler and i am trying to make them communicate through a SPI bus.

my problem is, I have no response from the w25q on my requests. For exemple, when i send the "get_id" protocol, it is supposed to send back the ID (as said in the datasheet), but i have nothing on the DO pin of the flash (so no answer from it).

I used STM32CubeMX to setup the pins (GPIO ans SPI), here is their configuration :

the SPI pins

 static void MX_SPI1_Init(void)
{

  /* SPI1 parameter configuration*/
  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_256; //312.25 Kbit/s
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

And the GPIO ports

static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, SPI_HOLD_Pin|SPI_WP_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : FLASH_CS_Pin */
  GPIO_InitStruct.Pin = FLASH_CS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(FLASH_CS_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : SPI_HOLD_Pin SPI_WP_Pin */
  GPIO_InitStruct.Pin = SPI_HOLD_Pin|SPI_WP_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

then I use a little test function in my main programm, i start by initialising the flash with the reset commands "0x66" to enable the reset and "0x99" to reset the devise.

  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET); //chipselect
  BufferSendFlash[0]=0x66;    //reset enable order
  HAL_SPI_Transmit(&hspi1, BufferSendFlash, 1, 1000);
  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET); //chip desselect
  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET); //chipselect
  BufferSendFlash[0]=0x99;   //reset devise order
  HAL_SPI_Transmit(&hspi1, BufferSendFlash, 1, 1000);
  HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET); //chipdesselect

my devise should be initialised now. Then I try to read the devise ID by sending the "0x90" command followed by 2 dummy bytes and 0x00 (as said in the datasheet) and i should recieve 2 bytes with the manufacturer and the ID right after. devise ID instruction datagram

HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET);
BufferSendFlash[0]=0x90;  //ask for ID instruction
BufferSendFlash[1]=0x00;  //dummy
BufferSendFlash[2]=0x00;  //dummy
BufferSendFlash[3]=0x00;  //end of address
HAL_SPI_Transmit(&hspi1, BufferSendFlash, 4, 1000);  //send the order
HAL_SPI_Receive(&hspi1,BufferReceiveFlash, 2, 1000);  //read the flash answer
HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET);

Here is what i see on the oscilloscope (i used a pull-up on the MOSI and MISO pins on the STM32) :
data input and output from flash

we can see that i have the clock and the order (sent from the MOSI pin of the stm32 to the DI pin of the flash) but we see on the DO (data output) pin, we have nothing, but the clock is here.

i might forgot a step in the initialisation of the flash but i can't figure it out since i followed the datasheet. I can't find anything on the web to help me so if someone have a solution to this problem, please help me, you are really welcome here ! thanks.

1
@old_timer Indeed it is said that the DI reads on the rising edge and the DO write on the falling edge of the clock (i didn't saw that earlyer thanks you). My CPOL is high, so i am sending my data on the rising edge of the CLK, but i have no idea if my MISO is reading on the falling edge of the clock. As i said, i am using STM32CubeMX and i can't find a way to set different configuration between MOSI and MISO. spi setup The maximum clockrate is 104 MHz, my clockrate is way bellow 104MHz (39.062 KBits/s) (i edited the post with better value measurement.)A.mickael
hold is driven or pulled high yes?old_timer
It was indeed a hardware problem with the hold pin, now the we changed the hardware setup, the flash does respond to the orders that i send. Thank you for your tips and help for my problem @old_timer.A.mickael

1 Answers

0
votes

As @old_timer suggested, i checked the HOLD pin and indeed, and indeed there was a problem with it. The problem was a hardware problem with the HOLD pin, the hold was allways low and we were not able to controle it. Now that we fixed the hardware setup, we can put the HOLD pin to high, and the flash listen and respond to input commands.

Thanks to @old_timer for the help.