Question
STM32 SPI problem
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