📄 spi_flash.c
字号:
Addr = WriteAddr % SPI_FLASH_PAGESIZE;
count = SPI_FLASH_PAGESIZE - Addr;
NumOfPage = NumByteToWrite / SPI_FLASH_PAGESIZE;
NumOfSingle = NumByteToWrite % SPI_FLASH_PAGESIZE;
if (Addr == 0) /* WriteAddr is SPI_FLASH_PAGESIZE aligned */
{
if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PAGESIZE */
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
}
else /* NumByteToWrite > SPI_FLASH_PAGESIZE */
{
while (NumOfPage--)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PAGESIZE);
WriteAddr += SPI_FLASH_PAGESIZE;
pBuffer += SPI_FLASH_PAGESIZE;
}
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
}
}
else /* WriteAddr is not SPI_FLASH_PAGESIZE aligned */
{
if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PAGESIZE */
{
if (NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PAGESIZE */
{
temp = NumOfSingle - count;
SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
}
else
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
}
}
else /* NumByteToWrite > SPI_FLASH_PAGESIZE */
{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / SPI_FLASH_PAGESIZE;
NumOfSingle = NumByteToWrite % SPI_FLASH_PAGESIZE;
SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
while (NumOfPage--)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PAGESIZE);
WriteAddr += SPI_FLASH_PAGESIZE;
pBuffer += SPI_FLASH_PAGESIZE;
}
if (NumOfSingle != 0)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
}
}
}
}
/**
* @brief Reads a block of data from the FLASH.
* @param pBuffer: pointer to the buffer that receives the data read from the FLASH.
* @param ReadAddr: FLASH's internal address to read from.
* @param NumByteToRead: number of bytes to read from the FLASH.
* @retval None
*/
void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Read from Memory " instruction */
SPI_FLASH_SendByte(CMD_READ);
/* Send ReadAddr high nibble address byte to read from */
SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
/* Send ReadAddr medium nibble address byte to read from */
SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
/* Send ReadAddr low nibble address byte to read from */
SPI_FLASH_SendByte(ReadAddr & 0xFF);
while (NumByteToRead--) /* while there is data to be read */
{
/* Read a byte from the FLASH */
*pBuffer = SPI_FLASH_SendByte(DUMMY_BYTE);
/* Point to the next location where the byte read will be saved */
pBuffer++;
}
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
}
/**
* @brief Reads FLASH identification.
* @param None
* @retval FLASH identification
*/
uint32_t SPI_FLASH_ReadID(void)
{
uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "RDID " instruction */
SPI_FLASH_SendByte(0x9F);
/* Read a byte from the FLASH */
Temp0 = SPI_FLASH_SendByte(DUMMY_BYTE);
/* Read a byte from the FLASH */
Temp1 = SPI_FLASH_SendByte(DUMMY_BYTE);
/* Read a byte from the FLASH */
Temp2 = SPI_FLASH_SendByte(DUMMY_BYTE);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return Temp;
}
/**
* @brief Initiates a read data byte (READ) sequence from the Flash.
* This is done by driving the /CS line low to select the device, then the READ
* instruction is transmitted followed by 3 bytes address. This function exit
* and keep the /CS line low, so the Flash still being selected. With this
* technique the whole content of the Flash is read with a single READ instruction.
* @param ReadAddr: FLASH's internal address to read from.
* @retval None
*/
void SPI_FLASH_StartReadSequence(uint32_t ReadAddr)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Read from Memory " instruction */
SPI_FLASH_SendByte(CMD_READ);
/* Send the 24-bit address of the address to read from ---------------------*/
/* Send ReadAddr high nibble address byte */
SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
/* Send ReadAddr medium nibble address byte */
SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
/* Send ReadAddr low nibble address byte */
SPI_FLASH_SendByte(ReadAddr & 0xFF);
}
/**
* @brief Reads a byte from the SPI Flash.
* @note This function must be used only if the Start_Read_Sequence function
* has been previously called.
* @param None
* @retval Byte Read from the SPI Flash.
*/
uint8_t SPI_FLASH_ReadByte(void)
{
return (SPI_FLASH_SendByte(DUMMY_BYTE));
}
/**
* @brief Sends a byte through the SPI interface and return the byte received
* from the SPI bus.
* @param byte: byte to send.
* @retval The value of the received byte.
*/
uint8_t SPI_FLASH_SendByte(uint8_t byte)
{
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI_FLASH, SPI_I2S_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */
SPI_I2S_SendData(SPI_FLASH, byte);
/* Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(SPI_FLASH, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI_FLASH);
}
/**
* @brief Sends a Half Word through the SPI interface and return the Half Word
* received from the SPI bus.
* @param HalfWord: Half Word to send.
* @retval The value of the received Half Word.
*/
uint16_t SPI_FLASH_SendHalfWord(uint16_t HalfWord)
{
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI_FLASH, SPI_I2S_FLAG_TXE) == RESET);
/* Send Half Word through the SPI_FLASH peripheral */
SPI_I2S_SendData(SPI_FLASH, HalfWord);
/* Wait to receive a Half Word */
while (SPI_I2S_GetFlagStatus(SPI_FLASH, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the Half Word read from the SPI bus */
return SPI_I2S_ReceiveData(SPI_FLASH);
}
/**
* @brief Enables the write access to the FLASH.
* @param None
* @retval None
*/
void SPI_FLASH_WriteEnable(void)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Write Enable" instruction */
SPI_FLASH_SendByte(CMD_WREN);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
}
/**
* @brief 写状态寄存器.(SST25VF016B)
* @param None
* @retval None
*/
void SPI_FLASH_WriteStatus(uint8_t data)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* 允许写状态寄存器 */
SPI_FLASH_SendByte(CMD_EWRSR);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* 允许写状态寄存器 */
SPI_FLASH_SendByte(CMD_WRSR);
SPI_FLASH_SendByte(data);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
}
/**
* @brief Polls the status of the Write In Progress (WIP) flag in the FLASH's
* status register and loop until write opertaion has completed.
* @param None
* @retval None
*/
void SPI_FLASH_WaitForWriteEnd(void)
{
uint8_t flashstatus = 0;
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Read Status Register" instruction */
SPI_FLASH_SendByte(CMD_RDSR);
/* 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 = SPI_FLASH_SendByte(DUMMY_BYTE);
}
while ((flashstatus & WIP_FLAG) == SET); /* Write in progress */
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
}
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -