cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI problem

muhammaduzairafzal45
Associate III
Posted on May 03, 2013 at 09:02

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)

  { }

}

#stm32 #spi-flash
3 REPLIES 3
muhammaduzairafzal45
Associate III
Posted on May 03, 2013 at 12:56

Ok, Found problem. Current was limit due to a resistor(2k) between MCU supply and SPI Flash. For page write or erase operation, 25mA is needed according to datasheet. Removed the resistor and now it works fine.

mhussnainraza_1986
Associate
Posted on May 06, 2015 at 15:07

hello,

I am programming Winbond SPI flash but i am unable to get the ID, when i am send the 0x9F instruction. SPI flash is giving me some random value.

I have connected the HOLD and WP pin to high but still having the same problem.

I am sending you code. 

void Delay(uint32_t time);

void SPI_GPIO();

void SPI_Config();

uint8_t SPI_SendByte(uint8_t byte);

uint32_t mfg = 0, memtype = 0, capacity = 0;

uint8_t DUMMY_BYTE = 0xFF;

int main(void)

  SPI_Config();

  GPIO_InitTypeDef GPIO_InitStructure; 

  /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

  while(1)

  {

    GPIO_SetBits(GPIOA,GPIO_Pin_4); /*!< Deselect the FLASH: Chip Select high */

       // Identity Check

  GPIO_ResetBits(GPIOA,GPIO_Pin_4); /*!< Select the FLASH: Chip Select Low */

  SPI_SendByte(0x90);

  /*!< Read a byte from the FLASH */

  Temp0 = SPI_SendByte(DUMMY_BYTE);

  /*!< Read a byte from the FLASH */

  Temp1 = SPI_SendByte(DUMMY_BYTE);

  /*!< Read a byte from the FLASH */

  Temp2 = SPI_SendByte(DUMMY_BYTE);

  /*!< Deselect the FLASH: Chip Select high */

  GPIO_SetBits(GPIOA,GPIO_Pin_4); /*!< Deselect the FLASH: Chip Select high */

  

  Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;

  GPIO_ToggleBits(GPIOD,GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15);

  Delay(5000000);

  }

}

void SPI_Config()

{

  SPI_InitTypeDef SPI_InitStructure;

  SPI_GPIO();

  GPIO_SetBits(GPIOA,GPIO_Pin_4); /*!< Deselect the FLASH: Chip Select high */

  

    // SPI Configuration

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;    // Set to full duplex

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                          // Transmit in master mode

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                     // One packet of data is 8 bits wide

  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                            // Clock is Low when idle

  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                          // Data sampled at First edge

  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                             // Set the NSS Soft

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;   // SPI Frequency is SPI Bus Clock/4

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                    // Data is transmitted MSB first

  SPI_InitStructure.SPI_CRCPolynomial = 7;  /*!< Specifies the polynomial used for the CRC calculation. */

  SPI_Init(SPI1 , &SPI_InitStructure);

  SPI_Cmd(SPI1 , ENABLE);

}

  

void SPI_GPIO()

{

  GPIO_InitTypeDef GPIO_InitStructure;

  /* SPI Periph clock enable */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

  /* Enable clock for used SPI IO pins */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

  /*!< Connect SPI pins to AF5 */ 

  

  GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_SPI1);     // SCK 

  GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_SPI1);     // MISO

  GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_SPI1);     // MOSI

  

  /* Pin  5=SCK, 6=MISO, 7=MOSI*/

  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  

  /*!< Configure CS pin in output pushpull mode ********************/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

}

uint8_t SPI_SendByte(uint8_t byte)

{

  /*!< Loop while DR register in not empty */

  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

  /*!< Send byte through the SPI1 peripheral */

  SPI_I2S_SendData(SPI1, byte);

  /*!< Wait to receive a byte */

  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

  /*!< Return the byte read from the SPI bus */

  return SPI_I2S_ReceiveData(SPI1);

}

void Delay(uint32_t time)

{

   int i = 100000;

   for(; time != 0; time--)     

     while(i!=0) i--;

   

}

Posted on May 06, 2015 at 18:04

You're sending 0x90 not 0x9F

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..