AnsweredAssumed Answered

STM32 SPI problem

Question asked by afzal.uzair on May 3, 2013
Latest reply on May 6, 2015 by Clive One
I want to interface winbond W25Q64BV SPI flash with STM32F103VE running at 24MHz. I was able to perfectly read the status registers and ID's of flash using commands 0x05,0x35,0x9F,0x4B,0x90,0xAB. But I am not able to erase or write data on flash. When I read the flash after erase chip command,I  am not getting 0xFF neither writing command is working. I have checked all memory protection bits and there is no protection set. Why am I not able to write or erase flash??

void sFLASH_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;


  sFLASH_LowLevel_Init();
    
  /*!< Deselect the FLASH: Chip Select high */
  sFLASH_CS_HIGH();


  /*!< SPI configuration */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//SPI_CPOL_High   SPI_CPOL_Low
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//SPI_CPHA_1Edge  SPI_CPHA_2Edge
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(sFLASH_SPI, &SPI_InitStructure);


  /*!< Enable the sFLASH_SPI  */
  SPI_Cmd(sFLASH_SPI, ENABLE);
}

void sFLASH_LowLevel_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;


  /*!< sFLASH_SPI_CS_GPIO, sFLASH_SPI_MOSI_GPIO, sFLASH_SPI_MISO_GPIO 
       and sFLASH_SPI_SCK_GPIO Periph clock enable */
  RCC_APB2PeriphClockCmd(sFLASH_CS_GPIO_CLK | sFLASH_SPI_MOSI_GPIO_CLK | sFLASH_SPI_MISO_GPIO_CLK |
                         sFLASH_SPI_SCK_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);


  /*!< sFLASH_SPI Periph clock enable */
  RCC_APB2PeriphClockCmd(sFLASH_SPI_CLK, ENABLE);
  
  /*!< Configure sFLASH_SPI pins: SCK */
  GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_SCK_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);


  /*!< Configure sFLASH_SPI pins: MOSI */
  GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MOSI_PIN;
  GPIO_Init(sFLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);


  /*!< Configure sFLASH_SPI pins: MISO */
  GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_MISO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  GPIO_Init(sFLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
  
  /*!< Configure sFLASH_CS_PIN pin: sFLASH Card CS pin */
  GPIO_InitStructure.GPIO_Pin = sFLASH_CS_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(sFLASH_CS_GPIO_PORT, &GPIO_InitStructure);
}

void sFLASH_EraseBulk(void)
{
  /*!< Send write enable instruction */
  sFLASH_WriteEnable();
  /*!< Bulk Erase */
  /*!< Select the FLASH: Chip Select low */
  sFLASH_CS_LOW();


  /*!< Send Bulk Erase instruction  */
  sFLASH_SendByte(sFLASH_CMD_ER_CHIP);
  /*!< Deselect the FLASH: Chip Select high */
  sFLASH_CS_HIGH();


  /*!< Wait the end of Flash writing */
  sFLASH_WaitForWriteEnd();
}

void sFLASH_WriteEnable(void)
{
  /*!< Select the FLASH: Chip Select low */
  sFLASH_CS_LOW();


  /*!< Send "Write Enable" instruction */
  sFLASH_SendByte(sFLASH_CMD_WR_ENABLE);


  /*!< Deselect the FLASH: Chip Select high */
  sFLASH_CS_HIGH();
}

void sFLASH_WaitForWriteEnd(void)
{
  uint8_t flashstatus = 0;


  /*!< Select the FLASH: Chip Select low */
  sFLASH_CS_LOW();


  /*!< Send "Read Status Register" instruction */
  sFLASH_SendByte(sFLASH_CMD_RD_STATUS_REG1);


  /*!< Loop as long as the memory is busy with a write cycle */
  do
  {
    /*!< Send a dummy byte to generate the clock needed by the FLASH
    and put the value of the status register in FLASH_Status variable */
    flashstatus = sFLASH_SendByte(sFLASH_DUMMY_BYTE);


  }
  while ((flashstatus & sFLASH_WIP_FLAG) == SET); /* Write in progress */


  /*!< Deselect the FLASH: Chip Select high */
  sFLASH_CS_HIGH();
}

uint8_t sFLASH_SendByte(uint8_t byte)
{
  /*!< Loop while DR register in not emplty */
  while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);


  /*!< Send byte through the SPI1 peripheral */
  SPI_I2S_SendData(sFLASH_SPI, byte);


  /*!< Wait to receive a byte */
  while (SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);


  /*!< Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(sFLASH_SPI);
}

void sFLASH_ReadBuffer(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
  /*!< Select the FLASH: Chip Select low */
  sFLASH_CS_LOW();


  /*!< Send "Read from Memory " instruction */
  sFLASH_SendByte(sFLASH_CMD_RD_DATA);


  /*!< Send ReadAddr high nibble address byte to read from */
  sFLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  /*!< Send ReadAddr medium nibble address byte to read from */
  sFLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  /*!< Send ReadAddr low nibble address byte to read from */
  sFLASH_SendByte(ReadAddr & 0xFF);


  while (NumByteToRead--) /*!< while there is data to be read */
  {
    /*!< Read a byte from the FLASH */
    *pBuffer = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
          USART1_Put(*pBuffer);
    /*!< Point to the next location where the byte read will be saved */
    pBuffer++;
  }


  /*!< Deselect the FLASH: Chip Select high */
  sFLASH_CS_HIGH();
}

int main(void)
{
     USART1_Config();
     
     //USART1_SendData_s("Main start::\n\r");
     // Initialize the SPI FLASH driver 
       sFLASH_Init();
     sFLASH_EraseBulk();
     sFLASH_ReadBuffer(Rx_Buffer, FLASH_ReadAddress, BufferSize);
      while (1)
       {     }
}

Outcomes